From b86d032e916d6d18ac2c05fd410457f18bdf2b6f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 23 Apr 2026 06:19:46 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=9E=20Sync=202026-04-23=2006:19:46?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cp210x-cfg/Makefile | 40 + event-handler/Makefile | 42 + event-handler/files/BTN_0 | 10 + event-handler/files/event-handler | 71 + event-handler/files/event-handler.config | 6 + event-handler/files/event-handler.init | 23 + fbfdownloader/Makefile | 36 + fbfdownloader/src/ApplicationINI.h | 432 ++ fbfdownloader/src/BinFileWtp.c | 353 + fbfdownloader/src/BinFileWtp.h | 51 + fbfdownloader/src/BulkDevNonDrv_Linux.c | 710 ++ fbfdownloader/src/BulkDevNonDrv_Linux.h | 156 + fbfdownloader/src/CommonFun.c | 190 + fbfdownloader/src/CommonFun.h | 41 + fbfdownloader/src/ConvetEdian.c | 60 + fbfdownloader/src/ConvetEdian.h | 16 + fbfdownloader/src/EnumVal.h | 145 + fbfdownloader/src/ErrorCode.h | 369 + fbfdownloader/src/FBFDownloader.c | 900 +++ fbfdownloader/src/FBFDownloader_makefile | 47 + .../src/FBFDownloader_makefile_android | 55 + .../src/FBFDownloader_makefile_cross | 55 + fbfdownloader/src/Macrodef.h | 141 + fbfdownloader/src/Makefile | 55 + fbfdownloader/src/ParaDefine.c | 161 + fbfdownloader/src/ParaDefine.h | 774 +++ fbfdownloader/src/ReadMe.txt | 9 + fbfdownloader/src/Tim.h | 960 +++ fbfdownloader/src/TimIncludedType.h | 36 + fbfdownloader/src/Typedef.h | 110 + fbfdownloader/src/UploadParaDef.h | 62 + fbfdownloader/src/WTPCOMMCLASS.c | 1409 ++++ fbfdownloader/src/WTPCOMMCLASS.h | 113 + fbfdownloader/src/WTPIOCTL.h | 134 + fbfdownloader/src/WTPdef.h | 186 + fbfdownloader/src/WtptpDownLoad.c | 21 + fbfdownloader/src/WtptpDownLoad.h | 7 + fbfdownloader/src/WtptpDownloader.c | 3386 +++++++++ fbfdownloader/src/WtptpDownloader.h | 229 + fbfdownloader/src/define.h | 145 + fbfdownloader/src/downloader.h | 377 + fbfdownloader/src/fbfdownload.h | 22 + fbfdownloader/src/khash.h | 627 ++ fbfdownloader/src/klist.h | 169 + fbfdownloader/src/kstring.c | 294 + fbfdownloader/src/kstring.h | 278 + fbfdownloader/src/libmakefile | 49 + fbfdownloader/src/libmakefile_cross | 56 + fbfdownloader/src/源码说明.txt | 72 + hotplug-generator/Makefile | 38 + hotplug-generator/files/hotplug.config | 8 + hotplug-generator/files/hotplug.init | 50 + iolines/Makefile | 38 + iolines/files/iolines.config | 23 + iolines/files/iolines.init | 112 + linux-serial-test/Makefile | 34 + luci-app-hotplug/Makefile | 2 +- .../root/etc/uci-defaults/hotplug | 19 - luci-app-pollmydevice/Makefile | 2 +- .../view/pollmydevice/pollmydevice.js | 6 +- .../root/etc/uci-defaults/powersupply | 19 - luci-app-pptpd/root/etc/uci-defaults/pptpd | 19 - luci-app-simman/Makefile | 2 +- luci-app-simman/root/etc/uci-defaults/simman | 19 - luci-app-smscontrol/Makefile | 2 +- .../root/etc/uci-defaults/smscontrol | 19 - .../root/etc/uci-defaults/snmpd-ssl | 19 - .../luci/menu.d/luci-app-strongswan.json | 1 - luci-app-xl2tpd/root/etc/uci-defaults/xl2tpd | 19 - luci-app-zabbix/Makefile | 2 +- luci-app-zabbix/root/etc/uci-defaults/zabbix | 19 - .../luasrc/view/themes/teleofis/footer.htm | 2 +- mxsldr/Makefile | 41 + mxsldr/src/COPYING | 339 + mxsldr/src/Makefile | 24 + mxsldr/src/README | 31 + mxsldr/src/hid1.diff | 11 + mxsldr/src/hid2.diff | 26 + mxsldr/src/mxsldr.c | 294 + net-snmp-ssl/Config.in.wut | 14 + net-snmp-ssl/Makefile | 287 + net-snmp-ssl/files/snmpd.init | 417 ++ net-snmp-ssl/files/snmptrapd.init | 15 + net-snmp-ssl/patches/000-cross-compile.patch | 47 + ...OST-MIB-hr_filesys-fix-compile-error.patch | 34 + .../patches/100-debian-statistics.patch | 13 + .../patches/110-debian-makefiles.patch | 40 + .../patches/120-debian-searchdirs.patch | 14 + .../patches/130-debian-extramibs.patch | 5183 ++++++++++++++ net-snmp-ssl/patches/160-no_ldconfig.patch | 11 + net-snmp-ssl/patches/161-project_types.patch | 11 + net-snmp-ssl/patches/170-ldflags.patch | 11 + .../patches/200-add-pcre2-support.patch | 407 ++ net-snmp-ssl/patches/201-Run-autoreconf.patch | 185 + .../patches/202-Improve-pcre2-support.patch | 152 + ...ss-interface.c-plug-a-leak-with-pcre.patch | 30 + net-snmp-ssl/patches/750-ieee802dot11.patch | 6166 +++++++++++++++++ net-snmp-ssl/patches/751-gcc-14-fix.patch | 10 + net-snmp-ssl/patches/900-musl-compat.patch | 13 + ...990-remove-semicolon-check-in-macros.patch | 130 + pingcontrol/Makefile | 4 +- pingcontrol/files/pingcontrol | 24 +- pingcontrol/files/pingcontrol.config | 1 - pingcontrol/files/pingcontrol.init | 5 - pollmydevice/Makefile | 51 + pollmydevice/files/console | 54 + pollmydevice/files/exp_board | 40 + pollmydevice/files/exp_port | 12 + pollmydevice/files/pollmydevice.config | 41 + pollmydevice/files/pollmydevice.defaults | 25 + pollmydevice/files/pollmydevice.init | 130 + pollmydevice/files/pollmydevice.rpcd | 34 + pollmydevice/files/printk.sysctl | 1 + pollmydevice/src/.vscode/settings.json | 6 + pollmydevice/src/Makefile | 14 + pollmydevice/src/client_list.c | 101 + pollmydevice/src/client_list.h | 9 + pollmydevice/src/crc16.c | 79 + pollmydevice/src/crc16.h | 41 + pollmydevice/src/globals.h | 103 + pollmydevice/src/log.h | 18 + pollmydevice/src/modbus.c | 93 + pollmydevice/src/modbus.h | 96 + pollmydevice/src/pollmydevice.c | 2083 ++++++ powersupply/Makefile | 40 + powersupply/files/powersupply.config | 10 + powersupply/files/powersupply.init | 62 + powersupply/files/powersupply.rpcd | 34 + pptpd-ext/Makefile | 50 + pptpd-ext/files/options.pptpd | 25 + pptpd-ext/files/pptp-down | 10 + pptpd-ext/files/pptp-up | 17 + pptpd-ext/files/pptpd.conf | 4 + pptpd-ext/files/pptpd.config | 4 + pptpd-ext/files/pptpd.init | 96 + report/Makefile | 38 + report/files/report | 65 + report/files/report.config | 11 + simman/Makefile | 65 + simman/README.md | 8 + simman/files/check_prio.sh | 176 + simman/files/getband.sh | 109 + simman/files/getbaseidinfo.gcom | 15 + simman/files/getbasestid.sh | 82 + simman/files/getbasestinfo.gcom | 15 + simman/files/getbasestinfo1.gcom | 17 + simman/files/getccid.gcom | 15 + simman/files/getccid.sh | 58 + simman/files/getccid1.gcom | 15 + simman/files/getccidnb.gcom | 19 + simman/files/getciccid.gcom | 15 + simman/files/getcsq.sh | 47 + simman/files/getenginfo.gcom | 30 + simman/files/getgprsreg.gcom | 15 + simman/files/getgprsreg.sh | 67 + simman/files/gethotswap.gcom | 18 + simman/files/getimei.gcom | 17 + simman/files/getimei.sh | 45 + simman/files/getimeinb.gcom | 19 + simman/files/getnettype.sh | 58 + simman/files/getpackinfo.gcom | 15 + simman/files/getpackinfo.sh | 140 + simman/files/getpackinfo1.gcom | 15 + simman/files/getpackinfolte.gcom | 15 + simman/files/getpinstat.gcom | 13 + simman/files/getpinstat.sh | 45 + simman/files/getreg.gcom | 15 + simman/files/getreg.sh | 63 + simman/files/getsiglev.gcom | 15 + simman/files/getsiglev.sh | 64 + simman/files/getsimcheck.sh | 63 + simman/files/gpsdata.gcom | 19 + simman/files/gpson.gcom | 15 + simman/files/nbinfo.sh | 74 + simman/files/scmux.hotplug | 99 + simman/files/sendat.gcom | 19 + simman/files/setfun.gcom | 21 + simman/files/setfun.sh | 45 + simman/files/setfunnb.gcom | 21 + simman/files/sethotswap.gcom | 15 + simman/files/setsim.sh | 325 + simman/files/simman.config | 55 + simman/files/simman.hotplug | 145 + simman/files/simman.init | 78 + simman/src/Makefile | 22 + simman/src/common.c | 549 ++ simman/src/common.h | 40 + simman/src/log.h | 18 + simman/src/simman.c | 813 +++ simman/src/simman_getinfo.c | 104 + simman2/Makefile | 55 + simman2/files/check_prio.sh | 176 + simman2/files/getccidnb.gcom | 19 + simman2/files/getimeinb.gcom | 19 + simman2/files/gpsdata.gcom | 19 + simman2/files/gpson.gcom | 15 + simman2/files/modeminit | 69 + simman2/files/nbinfo.sh | 74 + simman2/files/nbmodeminit | 41 + simman2/files/runcommand.gcom | 31 + simman2/files/setfunnb.gcom | 21 + simman2/files/setsim.sh | 296 + simman2/files/simman2.config | 34 + simman2/files/simman2.defaults | 27 + simman2/files/simman2.init | 70 + simman2/files/simman2.rpcd | 31 + simman2/src/Makefile | 18 + simman2/src/Makefile2 | 22 + simman2/src/common.c | 1059 +++ simman2/src/common.h | 146 + simman2/src/modem_a7600.c | 486 ++ simman2/src/modem_common.c | 272 + simman2/src/modem_ehs5.c | 228 + simman2/src/modem_sim5300.c | 298 + simman2/src/modem_sim5360.c | 302 + simman2/src/modem_sim7600.c | 374 + simman2/src/simman.c | 515 ++ simman2/src/simman_cli.c | 258 + smscontrol/Makefile | 41 + smscontrol/files/smscontrol.config | 26 + smscontrol/files/smscontrol.init | 140 + smscontrol/files/smshandler | 92 + smstools3-fix/Makefile | 65 + smstools3-fix/files/smstools3.conf | 24 + smstools3-fix/files/smstools3.init | 37 + smstools3-fix/patches/002-Makefile.patch | 11 + smstools3-fix/patches/003-bash-ash.patch | 8 + .../patches/004-modem-processes.patch | 24 + .../patches/005-smsd-to-uppercase.patch | 15 + stm32flash-gd/Makefile | 45 + .../001-add_support_for_custom_gd32.patch | 10 + svcontrol/Makefile | 38 + svcontrol/files/svcontrol | 19 + svcontrol/files/svcontrol.init | 15 + svupgrade/Makefile | 39 + svupgrade/files/gd3x.bin | Bin 0 -> 62960 bytes svupgrade/files/svupgrade.init | 37 + xl2tpd-ext/Makefile | 51 + xl2tpd-ext/files/l2tp-down | 10 + xl2tpd-ext/files/l2tp-up | 17 + xl2tpd-ext/files/l2tp.sh | 121 + xl2tpd-ext/files/options.xl2tpd | 24 + xl2tpd-ext/files/xl2tpd.conf | 23 + xl2tpd-ext/files/xl2tpd.config | 2 + xl2tpd-ext/files/xl2tpd.init | 107 + zabbix-config/Makefile | 44 + zabbix-config/files/device_template.conf | 18 + zabbix-config/files/zabbix.config | 3 + zabbix-config/files/zabbix_agentd.conf | 5 + zabbix-config/files/zabbix_agentd.init | 93 + 250 files changed, 41507 insertions(+), 188 deletions(-) create mode 100755 cp210x-cfg/Makefile create mode 100755 event-handler/Makefile create mode 100755 event-handler/files/BTN_0 create mode 100755 event-handler/files/event-handler create mode 100644 event-handler/files/event-handler.config create mode 100755 event-handler/files/event-handler.init create mode 100755 fbfdownloader/Makefile create mode 100644 fbfdownloader/src/ApplicationINI.h create mode 100644 fbfdownloader/src/BinFileWtp.c create mode 100644 fbfdownloader/src/BinFileWtp.h create mode 100644 fbfdownloader/src/BulkDevNonDrv_Linux.c create mode 100644 fbfdownloader/src/BulkDevNonDrv_Linux.h create mode 100644 fbfdownloader/src/CommonFun.c create mode 100644 fbfdownloader/src/CommonFun.h create mode 100644 fbfdownloader/src/ConvetEdian.c create mode 100644 fbfdownloader/src/ConvetEdian.h create mode 100644 fbfdownloader/src/EnumVal.h create mode 100644 fbfdownloader/src/ErrorCode.h create mode 100644 fbfdownloader/src/FBFDownloader.c create mode 100644 fbfdownloader/src/FBFDownloader_makefile create mode 100644 fbfdownloader/src/FBFDownloader_makefile_android create mode 100644 fbfdownloader/src/FBFDownloader_makefile_cross create mode 100644 fbfdownloader/src/Macrodef.h create mode 100644 fbfdownloader/src/Makefile create mode 100644 fbfdownloader/src/ParaDefine.c create mode 100644 fbfdownloader/src/ParaDefine.h create mode 100644 fbfdownloader/src/ReadMe.txt create mode 100644 fbfdownloader/src/Tim.h create mode 100644 fbfdownloader/src/TimIncludedType.h create mode 100644 fbfdownloader/src/Typedef.h create mode 100644 fbfdownloader/src/UploadParaDef.h create mode 100644 fbfdownloader/src/WTPCOMMCLASS.c create mode 100644 fbfdownloader/src/WTPCOMMCLASS.h create mode 100644 fbfdownloader/src/WTPIOCTL.h create mode 100644 fbfdownloader/src/WTPdef.h create mode 100644 fbfdownloader/src/WtptpDownLoad.c create mode 100644 fbfdownloader/src/WtptpDownLoad.h create mode 100644 fbfdownloader/src/WtptpDownloader.c create mode 100644 fbfdownloader/src/WtptpDownloader.h create mode 100644 fbfdownloader/src/define.h create mode 100644 fbfdownloader/src/downloader.h create mode 100644 fbfdownloader/src/fbfdownload.h create mode 100644 fbfdownloader/src/khash.h create mode 100644 fbfdownloader/src/klist.h create mode 100644 fbfdownloader/src/kstring.c create mode 100644 fbfdownloader/src/kstring.h create mode 100644 fbfdownloader/src/libmakefile create mode 100644 fbfdownloader/src/libmakefile_cross create mode 100644 fbfdownloader/src/源码说明.txt create mode 100755 hotplug-generator/Makefile create mode 100755 hotplug-generator/files/hotplug.config create mode 100755 hotplug-generator/files/hotplug.init create mode 100755 iolines/Makefile create mode 100644 iolines/files/iolines.config create mode 100755 iolines/files/iolines.init create mode 100644 linux-serial-test/Makefile delete mode 100644 luci-app-hotplug/root/etc/uci-defaults/hotplug delete mode 100644 luci-app-powersupply/root/etc/uci-defaults/powersupply delete mode 100644 luci-app-pptpd/root/etc/uci-defaults/pptpd delete mode 100644 luci-app-simman/root/etc/uci-defaults/simman delete mode 100644 luci-app-smscontrol/root/etc/uci-defaults/smscontrol delete mode 100644 luci-app-snmpd-ssl/root/etc/uci-defaults/snmpd-ssl delete mode 100644 luci-app-xl2tpd/root/etc/uci-defaults/xl2tpd delete mode 100644 luci-app-zabbix/root/etc/uci-defaults/zabbix create mode 100644 mxsldr/Makefile create mode 100644 mxsldr/src/COPYING create mode 100644 mxsldr/src/Makefile create mode 100644 mxsldr/src/README create mode 100644 mxsldr/src/hid1.diff create mode 100644 mxsldr/src/hid2.diff create mode 100644 mxsldr/src/mxsldr.c create mode 100644 net-snmp-ssl/Config.in.wut create mode 100644 net-snmp-ssl/Makefile create mode 100644 net-snmp-ssl/files/snmpd.init create mode 100644 net-snmp-ssl/files/snmptrapd.init create mode 100644 net-snmp-ssl/patches/000-cross-compile.patch create mode 100644 net-snmp-ssl/patches/010-HOST-MIB-hr_filesys-fix-compile-error.patch create mode 100644 net-snmp-ssl/patches/100-debian-statistics.patch create mode 100644 net-snmp-ssl/patches/110-debian-makefiles.patch create mode 100644 net-snmp-ssl/patches/120-debian-searchdirs.patch create mode 100644 net-snmp-ssl/patches/130-debian-extramibs.patch create mode 100644 net-snmp-ssl/patches/160-no_ldconfig.patch create mode 100644 net-snmp-ssl/patches/161-project_types.patch create mode 100644 net-snmp-ssl/patches/170-ldflags.patch create mode 100644 net-snmp-ssl/patches/200-add-pcre2-support.patch create mode 100644 net-snmp-ssl/patches/201-Run-autoreconf.patch create mode 100644 net-snmp-ssl/patches/202-Improve-pcre2-support.patch create mode 100644 net-snmp-ssl/patches/203-if-mib-data_access-interface.c-plug-a-leak-with-pcre.patch create mode 100644 net-snmp-ssl/patches/750-ieee802dot11.patch create mode 100644 net-snmp-ssl/patches/751-gcc-14-fix.patch create mode 100644 net-snmp-ssl/patches/900-musl-compat.patch create mode 100644 net-snmp-ssl/patches/990-remove-semicolon-check-in-macros.patch create mode 100644 pollmydevice/Makefile create mode 100755 pollmydevice/files/console create mode 100755 pollmydevice/files/exp_board create mode 100755 pollmydevice/files/exp_port create mode 100755 pollmydevice/files/pollmydevice.config create mode 100755 pollmydevice/files/pollmydevice.defaults create mode 100644 pollmydevice/files/pollmydevice.init create mode 100755 pollmydevice/files/pollmydevice.rpcd create mode 100755 pollmydevice/files/printk.sysctl create mode 100644 pollmydevice/src/.vscode/settings.json create mode 100644 pollmydevice/src/Makefile create mode 100644 pollmydevice/src/client_list.c create mode 100644 pollmydevice/src/client_list.h create mode 100644 pollmydevice/src/crc16.c create mode 100644 pollmydevice/src/crc16.h create mode 100644 pollmydevice/src/globals.h create mode 100644 pollmydevice/src/log.h create mode 100644 pollmydevice/src/modbus.c create mode 100644 pollmydevice/src/modbus.h create mode 100755 pollmydevice/src/pollmydevice.c create mode 100755 powersupply/Makefile create mode 100644 powersupply/files/powersupply.config create mode 100755 powersupply/files/powersupply.init create mode 100755 powersupply/files/powersupply.rpcd create mode 100755 pptpd-ext/Makefile create mode 100644 pptpd-ext/files/options.pptpd create mode 100644 pptpd-ext/files/pptp-down create mode 100644 pptpd-ext/files/pptp-up create mode 100644 pptpd-ext/files/pptpd.conf create mode 100644 pptpd-ext/files/pptpd.config create mode 100644 pptpd-ext/files/pptpd.init create mode 100755 report/Makefile create mode 100755 report/files/report create mode 100644 report/files/report.config create mode 100755 simman/Makefile create mode 100755 simman/README.md create mode 100755 simman/files/check_prio.sh create mode 100755 simman/files/getband.sh create mode 100755 simman/files/getbaseidinfo.gcom create mode 100755 simman/files/getbasestid.sh create mode 100755 simman/files/getbasestinfo.gcom create mode 100755 simman/files/getbasestinfo1.gcom create mode 100755 simman/files/getccid.gcom create mode 100755 simman/files/getccid.sh create mode 100755 simman/files/getccid1.gcom create mode 100755 simman/files/getccidnb.gcom create mode 100755 simman/files/getciccid.gcom create mode 100755 simman/files/getcsq.sh create mode 100755 simman/files/getenginfo.gcom create mode 100755 simman/files/getgprsreg.gcom create mode 100755 simman/files/getgprsreg.sh create mode 100755 simman/files/gethotswap.gcom create mode 100755 simman/files/getimei.gcom create mode 100755 simman/files/getimei.sh create mode 100644 simman/files/getimeinb.gcom create mode 100755 simman/files/getnettype.sh create mode 100755 simman/files/getpackinfo.gcom create mode 100755 simman/files/getpackinfo.sh create mode 100755 simman/files/getpackinfo1.gcom create mode 100755 simman/files/getpackinfolte.gcom create mode 100755 simman/files/getpinstat.gcom create mode 100755 simman/files/getpinstat.sh create mode 100755 simman/files/getreg.gcom create mode 100755 simman/files/getreg.sh create mode 100755 simman/files/getsiglev.gcom create mode 100755 simman/files/getsiglev.sh create mode 100755 simman/files/getsimcheck.sh create mode 100644 simman/files/gpsdata.gcom create mode 100755 simman/files/gpson.gcom create mode 100755 simman/files/nbinfo.sh create mode 100755 simman/files/scmux.hotplug create mode 100755 simman/files/sendat.gcom create mode 100755 simman/files/setfun.gcom create mode 100755 simman/files/setfun.sh create mode 100755 simman/files/setfunnb.gcom create mode 100755 simman/files/sethotswap.gcom create mode 100755 simman/files/setsim.sh create mode 100755 simman/files/simman.config create mode 100755 simman/files/simman.hotplug create mode 100755 simman/files/simman.init create mode 100755 simman/src/Makefile create mode 100755 simman/src/common.c create mode 100755 simman/src/common.h create mode 100755 simman/src/log.h create mode 100755 simman/src/simman.c create mode 100755 simman/src/simman_getinfo.c create mode 100755 simman2/Makefile create mode 100755 simman2/files/check_prio.sh create mode 100755 simman2/files/getccidnb.gcom create mode 100644 simman2/files/getimeinb.gcom create mode 100644 simman2/files/gpsdata.gcom create mode 100755 simman2/files/gpson.gcom create mode 100644 simman2/files/modeminit create mode 100755 simman2/files/nbinfo.sh create mode 100644 simman2/files/nbmodeminit create mode 100644 simman2/files/runcommand.gcom create mode 100755 simman2/files/setfunnb.gcom create mode 100755 simman2/files/setsim.sh create mode 100755 simman2/files/simman2.config create mode 100755 simman2/files/simman2.defaults create mode 100755 simman2/files/simman2.init create mode 100644 simman2/files/simman2.rpcd create mode 100755 simman2/src/Makefile create mode 100755 simman2/src/Makefile2 create mode 100755 simman2/src/common.c create mode 100755 simman2/src/common.h create mode 100755 simman2/src/modem_a7600.c create mode 100755 simman2/src/modem_common.c create mode 100755 simman2/src/modem_ehs5.c create mode 100755 simman2/src/modem_sim5300.c create mode 100755 simman2/src/modem_sim5360.c create mode 100755 simman2/src/modem_sim7600.c create mode 100755 simman2/src/simman.c create mode 100755 simman2/src/simman_cli.c create mode 100755 smscontrol/Makefile create mode 100644 smscontrol/files/smscontrol.config create mode 100755 smscontrol/files/smscontrol.init create mode 100755 smscontrol/files/smshandler create mode 100644 smstools3-fix/Makefile create mode 100644 smstools3-fix/files/smstools3.conf create mode 100644 smstools3-fix/files/smstools3.init create mode 100644 smstools3-fix/patches/002-Makefile.patch create mode 100644 smstools3-fix/patches/003-bash-ash.patch create mode 100644 smstools3-fix/patches/004-modem-processes.patch create mode 100644 smstools3-fix/patches/005-smsd-to-uppercase.patch create mode 100644 stm32flash-gd/Makefile create mode 100644 stm32flash-gd/patches/001-add_support_for_custom_gd32.patch create mode 100755 svcontrol/Makefile create mode 100755 svcontrol/files/svcontrol create mode 100755 svcontrol/files/svcontrol.init create mode 100755 svupgrade/Makefile create mode 100644 svupgrade/files/gd3x.bin create mode 100755 svupgrade/files/svupgrade.init create mode 100755 xl2tpd-ext/Makefile create mode 100644 xl2tpd-ext/files/l2tp-down create mode 100644 xl2tpd-ext/files/l2tp-up create mode 100644 xl2tpd-ext/files/l2tp.sh create mode 100644 xl2tpd-ext/files/options.xl2tpd create mode 100644 xl2tpd-ext/files/xl2tpd.conf create mode 100644 xl2tpd-ext/files/xl2tpd.config create mode 100644 xl2tpd-ext/files/xl2tpd.init create mode 100755 zabbix-config/Makefile create mode 100644 zabbix-config/files/device_template.conf create mode 100644 zabbix-config/files/zabbix.config create mode 100644 zabbix-config/files/zabbix_agentd.conf create mode 100755 zabbix-config/files/zabbix_agentd.init diff --git a/cp210x-cfg/Makefile b/cp210x-cfg/Makefile new file mode 100755 index 00000000..09f77243 --- /dev/null +++ b/cp210x-cfg/Makefile @@ -0,0 +1,40 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=cp210x-cfg +PKG_VERSION:=1 +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL=https://github.com/iuncuim/cp210x-cfg.git +PKG_SOURCE_DATE:=2023-05-18 +PKG_SOURCE_VERSION:=bf968c49c7cf004ebfba72f7deb0ba88330e1652 +PKG_MIRROR_HASH:=skip + +include $(INCLUDE_DIR)/package.mk + +define Package/cp210x-cfg + SECTION:=utils + CATEGORY:=Utilities + TITLE:=CLI utility for programming CP210x USB<->UART bridges + DEPENDS:=+libusb-1.0 +endef + +TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include +TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib + +define Package/cp210x-cfg/description + CLI utility for programming CP210x USB<->UART bridges +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Package/cp210x-cfg/install + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/cp210x-cfg $(1)/sbin/ +endef + +$(eval $(call BuildPackage,cp210x-cfg)) diff --git a/event-handler/Makefile b/event-handler/Makefile new file mode 100755 index 00000000..137cb0ba --- /dev/null +++ b/event-handler/Makefile @@ -0,0 +1,42 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=event-handler +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/event-handler + +include $(INCLUDE_DIR)/package.mk + +define Package/event-handler + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Event Handler for lt70 + PKGARCH:=all +endef + +define Package/event-handler/description + This package contains a utility +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/event-handler/install + $(INSTALL_DIR) $(1)/bin + $(INSTALL_BIN) ./files/event-handler $(1)/bin/ + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/event-handler.config $(1)/etc/config/event-handler + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/event-handler.init $(1)/etc/init.d/event-handler + $(INSTALL_DIR) $(1)/etc/rc.button + $(INSTALL_BIN) ./files/BTN_0 $(1)/etc/rc.button/ +endef + +$(eval $(call BuildPackage,event-handler)) diff --git a/event-handler/files/BTN_0 b/event-handler/files/BTN_0 new file mode 100755 index 00000000..06ceaf1b --- /dev/null +++ b/event-handler/files/BTN_0 @@ -0,0 +1,10 @@ +#!/bin/sh + +if [ "${ACTION}" = "released" ]; then + #logger "gd3x: waiting for interrupt" +fi + +if [ "${ACTION}" = "pressed" ]; then + event-handler int + #logger "gd3x: new interrupt" +fi diff --git a/event-handler/files/event-handler b/event-handler/files/event-handler new file mode 100755 index 00000000..81906d8d --- /dev/null +++ b/event-handler/files/event-handler @@ -0,0 +1,71 @@ +#!/bin/sh +POE="$(uci -q get event-handler.@event-handler[0].poe_gpio)" +USB="$(uci -q get event-handler.@event-handler[0].usb_gpio)" +HEAT="$(uci -q get event-handler.@event-handler[0].heat_gpio)" +WD="$(uci -q get event-handler.@event-handler[0].wd_gpio)" +LOG=/etc/event_log +int=$1 + +while true; do + touch $LOG + DATE=$(date) + INTS_MASK=$(cat /sys/class/i2c-dev/i2c-0/device/0-0011/int_sum) + + # poe out power error int + if [[ "$(echo $((INTS_MASK & 1)))" == "1" ]]; then + VALUE=$(cat /sys/class/gpio/gpio$POE/value) + if [[ "$VALUE" == "1" ]]; then + echo "$DATE: ${int:+$int: }poe: Warning! The maximum current limit on the PoE-OUT output has been exceeded." >> $LOG + else + echo "$DATE: ${int:+$int: }poe: The PoE-OUT output current has been restored to normal values after exceeding the maximum thresholds." >> $LOG + fi + fi + + # usb power error int + if [[ "$(echo $((INTS_MASK & 2)))" == "2" ]]; then + VALUE=$(cat /sys/class/gpio/gpio$USB/value) + if [[ "$VALUE" == "1" ]]; then + echo "$DATE: ${int:+$int: }usb: Warning! The maximum current limit for the USB has been exceeded." >> $LOG + else + echo "$DATE: ${int:+$int: }usb: The USB current has been restored to normal values after exceeding the maximum threshold." >> $LOG + fi + fi + + # heat int + if [[ "$(echo $((INTS_MASK & 4)))" == "4" ]]; then + VALUE=$(cat /sys/class/gpio/gpio$HEAT/value) + if [[ "$VALUE" == "1" ]]; then + echo "$DATE: ${int:+$int: }heat: The device heating circuit is enabled." >> $LOG + else + echo "$DATE: ${int:+$int: }heat: The device heating circuit is disabled." >> $LOG + fi + fi + + # wd toggle int + if [[ "$(echo $((INTS_MASK & 8)))" == "8" ]]; then + VALUE=$(cat /sys/class/gpio/gpio$WD/value) + fi + + # voltage threshold int + if [[ "$(echo $((INTS_MASK & 16)))" == "16" ]]; then + input_voltage="$(cat /sys/class/i2c-dev/i2c-0/device/0-0011/input_voltage)" + voltage_threshold="$(cat /sys/class/i2c-dev/i2c-0/device/0-0011/voltage_threshold)" + poe_out_power_gpio="$(uci -q get powersupply.system.poe_out_power_gpio)" + if [[ "$input_voltage" -lt "$voltage_threshold" ]]; then + echo 0 > /sys/class/gpio/gpio$poe_out_power_gpio/value + echo "$DATE: ${int:+$int: }voltage: PoE-OUT power supply is disabled. The input voltage is below the required threshold of $voltage_threshold mV DC. Current voltage: $input_voltage mV." >> $LOG + fi + fi + + if [[ "$(wc -l < $LOG)" -ge "100" ]]; then + mv $LOG $LOG.old + fi + + if [[ -n "$int" ]]; then + break + fi + + sleep 1 +done + +exit 0 diff --git a/event-handler/files/event-handler.config b/event-handler/files/event-handler.config new file mode 100644 index 00000000..ede2407d --- /dev/null +++ b/event-handler/files/event-handler.config @@ -0,0 +1,6 @@ +config event-handler + option poe_gpio '632' + option usb_gpio '633' + option heat_gpio '634' + option wd_gpio '635' + diff --git a/event-handler/files/event-handler.init b/event-handler/files/event-handler.init new file mode 100755 index 00000000..13a1a20c --- /dev/null +++ b/event-handler/files/event-handler.init @@ -0,0 +1,23 @@ +#!/bin/sh /etc/rc.common + +START=11 +USE_PROCD=1 +PROG=/bin/event-handler + +start_service() { + touch /etc/event_log + poe_gpio="$(uci -q get event-handler.@event-handler[0].poe_gpio)" + echo $poe_gpio > /sys/class/gpio/export + usb_gpio="$(uci -q get event-handler.@event-handler[0].usb_gpio)" + echo $usb_gpio > /sys/class/gpio/export + heat_gpio="$(uci -q get event-handler.@event-handler[0].heat_gpio)" + echo $heat_gpio > /sys/class/gpio/export + wd_gpio="$(uci -q get event-handler.@event-handler[0].wd_gpio)" + echo $wd_gpio > /sys/class/gpio/export + procd_open_instance + procd_set_param command "$PROG" + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_set_param respawn + procd_close_instance +} diff --git a/fbfdownloader/Makefile b/fbfdownloader/Makefile new file mode 100755 index 00000000..47dea3c7 --- /dev/null +++ b/fbfdownloader/Makefile @@ -0,0 +1,36 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=fbfdownloader +PKG_VERSION:=4.9.0.7 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/fbfdownloader + + +include $(INCLUDE_DIR)/package.mk + +define Package/fbfdownloader + SECTION:=utils + CATEGORY:=Utilities + DEPENDS+= +libpthread + TITLE:=Firmware flash tool for ASR based modems +endef + +TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include +TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib + +define Package/fbfdownloader/description + This package contains utility for sim check manage. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Package/fbfdownloader/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/fbfdownloader_cross $(1)/usr/bin +endef + +$(eval $(call BuildPackage,fbfdownloader)) diff --git a/fbfdownloader/src/ApplicationINI.h b/fbfdownloader/src/ApplicationINI.h new file mode 100644 index 00000000..79b6302e --- /dev/null +++ b/fbfdownloader/src/ApplicationINI.h @@ -0,0 +1,432 @@ + +// +////////////////////////////////////////////////////////////////////// + +#pragma once +#pragma warning ( disable : 4100 ) // Disable warning messages: unreferenced formal parameter +#pragma warning ( disable : 4189 ) // Disable warning messages: local variable is initialized but not referenced +#include "Macrodef.h" +//#include "BLFProperty.h" +#include "EnumVal.h" +#define MAX_FILE_LENGTH 1024 +#define SECTOR_UNIT 512 +#define EMMC_ERASE_UNIT (512*1024) // 512K +#define NAND_ERASE_UNIT (128*1024) // 128K +#define NOR_ERASE_UNIT (64*1024) // 64K +#define READ_BLOCK_SIZE 0x800000 //8M + +//different partitions of EMMC +#define PRIBOOT_PARTITION 1 +#define RECVBOOT_PARTITION 2 +#define RPMB_PARTITION 3 +/* general commands */ +#define DLCMD_DO_ERASE_ALL_FLASH (1) +#define DLCMD_DO_UPLOAD_DATA (2) +#define DLCMD_RESETBBT (4) +#define DLCMD_DO_ERASE_ALL_ONLY (16) + +const static TCHAR* FBF_IDNAME = _T("FBFD"); +const static TCHAR* DKB_IDNAME = _T("DKBI"); +const static TCHAR* OBM_IDNAME = _T("OBMI"); +const static TCHAR* WTM_IDNAME = _T("WTMI"); +const static TCHAR* TZI_IDNAME = _T("TZII"); +const static TCHAR* ROMC_IDNAME = _T("ROMC"); +const static TCHAR* FBF_IMAGE_TYPE = _T("FBF"); + +const static TCHAR* pszDKB_TIM_HEADER_NAME = _T("DKB_ntimheader.bin"); +const static TCHAR* pszDKB_TRUST_TIM_HEADER_NAME = _T("DKB_timheader.bin"); +const static TCHAR* pszDKB_DUMMY_BIN = _T("DKB_dummy.bin"); +const static TCHAR* pszFBF_NTIM_HEADER_NAME = _T("FBF_Ntimheader.bin"); +const static TCHAR* pszFBF_TRUST_TIM_HEADER_NAME = _T("FBF_timheader.bin"); +const static TCHAR* pszDKB_FILE_NAME = _T("Dkb.bin"); +const static TCHAR* pszPREFERENCES = _T("Preferences"); +const static TCHAR* pszRUN_TIME_DLG = _T("Run-Time Dialog"); +const static TCHAR* pszTIM_CFG = _T("TIM_Configuration"); +const static TCHAR* pszBLF_VERSION_PRO = _T("BLF_Version"); +const static TCHAR* pszBLF_VERSION_NUMBER = _T("V2.0.0"); +const static TCHAR* pszBLF_VERSION_NUMBER_SECTOR_FLASH = _T("V2.1.0"); +const static TCHAR* pszBLF_VERSION_NUMBER_SECTOR_FLASH_WITH_DTIMPPSETTING = _T("V2.2.0"); +const static TCHAR* pszBLF_VERSION_NAND_NOR_FLASH = _T("V3.0.0"); +const static TCHAR* pszBLF_VERSION = _T("Blf_Version_Number"); +const static TCHAR* pszRESET_BBT = _T("Reset_BBT"); +const static TCHAR* pszFBF_SECTOR_SIZE = _T("FBF_Sector_Size"); +const static TCHAR* pszDATA_PAGE_SIZE = _T("Data_Area_Size" ); +const static TCHAR* pszSPARE_AREA_SIZE = _T("Spare_Area_Size" ); +const static TCHAR* pszNAND_BLOCK_SIZE = _T("Flash_Block_Size"); +const static TCHAR* pszMAX_OTA_IAMGE_SIZE = _T("Max_OTA_Image_Size"); +const static TCHAR* pszOTA_IAMGE_SPLIT_SIZE = _T("OTA_Image_Split_Size"); +const static TCHAR* pszFLASH_FAMILY_PRO = _T("Flash_Family" ); +const static TCHAR* pszSKIP_BLOCK_NUMBER = _T("Skip_Blocks_Number"); +const static TCHAR* pszERASE_ALL_FLASH = _T("Erase_All_Flash"); +const static TCHAR* pszBOOTOPTION_AFTER_FLASH = _T("UE_Boot_Option"); +const static TCHAR* pszPROCESSOR_TYPE = _T("Processor_Type"); +const static TCHAR* pszBOOT_FLASH_SIG = _T("Boot_Flash_Signature"); +const static TCHAR* pszTRUSTED = _T("Trusted"); +const static TCHAR* pszVERSION = _T("Version"); +const static TCHAR* pszISSUDT = _T("Issue_Date"); +const static TCHAR* pszOEMUID = _T("OEM_UniqueID"); +const static TCHAR* pszSIZE_OF_IMG = _T("Number_of_Images"); +const static TCHAR* pszSIZE_OF_EMMCTYPE = _T("Number_of_EMMCTypes"); +const static TCHAR* pszSIZE_OF_RSV = _T("Size_of_Reserved_in_bytes"); +const static TCHAR* pszNUM_OF_KEYS = _T("Number_of_Keys"); +const static TCHAR* pszEXT_RSV_DATA = _T("[Extended_Reserved_Data]"); +const static TCHAR* pszRSV_DATA = _T("[Reserved_Data]"); +const static TCHAR* pszEND_RSV_DATA = _T("End_Reserved_Data"); +const static TCHAR* pszFBF_SPLIT_SIZE_SETTING = _T("Max_FBF_Split_Size"); +const static TCHAR* pszUPLOAD_MAX_SIZE_SETTING = _T("Max_Upload_Split_Size" ); +const static TCHAR* pszWTM_FL_SIGTURE = _T("WTM_Save_State_Flash_Signature"); +const static TCHAR* pszWTM_FL_EN_ADDR = _T("WTM_Save_State_Flash_Entry_Address"); +const static TCHAR* pszWTM_BK_EN_ADDR = _T("WTM_Save_State_BackUp_Entry_Address"); + + +const static TCHAR* pszAUTH_PATH = _T("Authentication Path"); +const static TCHAR* pszST_ADDR = _T("Start_Address"); +const static TCHAR* pszIMG_LIST = _T("Image_List"); +const static TCHAR* pszENBL = _T("Enable"); +const static TCHAR* pszTIM_INCLUDED = _T("Tim_Included"); +const static TCHAR* pszPATH = _T("Path"); +const static TCHAR* pszFL_ENTRY_ADDR = _T("Flash_Entry_Address"); +const static TCHAR* pszLOAD_ADDR = _T("Load_Address"); +const static TCHAR* pszSIZE_OF_IMGTOCRC = _T("Size_To_CRC_in_bytes"); +const static TCHAR* pszSIZE_OF_IMGTOHASH = _T("Image_Size_To_Hash_in_bytes"); +const static TCHAR* pszSIZE_OF_ERASE = _T("Erase_Size"); +const static TCHAR* pszPARTITION = _T("Partition_Number"); +const static TCHAR* pszIMGID_NAME = _T("ID_Name"); +const static TCHAR* pszIMGID = _T("Image_ID"); +const static TCHAR* pszNTIMGID = _T("Next_Image_ID"); +const static TCHAR* pszHASH_ALGT_ID = _T("Hash_Algorithm_ID"); +const static TCHAR* pszOFST = _T("Offset"); +const static TCHAR* pszTYPE = _T("Type"); +const static TCHAR* pszFLASH_PROP = _T("Flash_Properties"); +const static TCHAR* pszFLASH_OPTIONS = _T("Flash_Options"); +const static TCHAR* pszUE_OPTIONS = _T("UE_Options"); +const static TCHAR* pszNONE_ERASESIZE = _T(""); +const static TCHAR* pszSPARE_SIZE = _T("Spare_Area_Size"); +const static TCHAR* pszDATA_SIZE = _T("Data_Area_Size"); +const static TCHAR* pszFLASHNANDID = _T("Flash_NandID"); +const static TCHAR* pszJTAG_TRUSTED = _T("JTAG TRUSTED"); +const static TCHAR* pszJTAG_TIM = _T("TIM Path"); +const static TCHAR* pszJTAG_KEY = _T("KEY Path"); +const static TCHAR* pszPACKAGE_SIZE = _T("Package_Size"); + + + +const static TCHAR* pszERASE_ONLY_OPTION = _T("EraseOnly_Option"); +const static TCHAR* pszERASE_ONLY_NUM = _T("Total_Eraseonly_Areas"); +const static TCHAR* pszERASE_ONLY_START_ADD = _T("Eraseonly_Area_FlashStartAddress"); +const static TCHAR* pszERASE_ONLY_SIZE = _T("Eraseonly_Area_Size"); +const static TCHAR* pszERASE_ONLY_PARTITION = _T("Eraseonly_Area_Partition"); + + +//Add support for trusted mode +const static TCHAR* pszDIGITAL_SIGNATURE_DATA = _T("Digital_Signature_Data"); +const static TCHAR* pszEND_DIGITAL_SIGNATURE_DATA = _T("End_Digital_Signature_Data"); +const static TCHAR* pszKEYS_DATA = _T("Keys_Data"); +const static TCHAR* pszDSA_ALGORITHM = _T("DSA_Algorithm"); +const static TCHAR* pszHASHALG_ID = _T("Hash_Algorithm_ID"); +const static TCHAR* pszENCRYPT_ALGID = _T("Encrypt_Algorithm_ID"); +const static TCHAR* pszKEY_ID = _T("Key_ID"); +const static TCHAR* pszMODULUS_SIZE = _T("Modulus_Size_in_bytes"); +const static TCHAR* pszKEY_SIZE = _T("Key_Size_in_bits"); +const static TCHAR* pszPUBLIC_KEY_SIZE = _T("Public_Key_Size_in_bytes"); +const static TCHAR* pszRSA_PUBLIC_EXP = _T("RSA_Public_Exponent"); +const static TCHAR* pszEND_RSA_PUBLIC_EXP = _T("End_RSA_Public_Exponent"); +const static TCHAR* pszRSA_SYS_MODULUS = _T("RSA_System_Modulus"); +const static TCHAR* pszEND_RSA_SYS_MODULUS = _T("End_RSA_System_Modulus"); +const static TCHAR* pszRSA_PRIVATE_KEY = _T("RSA_Private_Key"); +const static TCHAR* pszEND_RSA_PRIVATE_KEY = _T("End_RSA_Private_Key"); +const static TCHAR* pszECDSA_PUBLIC_KEY_COMX = _T("ECDSA_Public_Key_CompX"); +const static TCHAR* pszEND_ECDSA_PUBLIC_KEY_COMX = _T("End_ECDSA_Public_Key_CompX"); +const static TCHAR* pszECDSA_PUBLIC_KEY_COMY = _T("ECDSA_Public_Key_CompY"); +const static TCHAR* pszEND_ECDSA_PUBLIC_KEY_COMY = _T("End_ECDSA_Public_Key_CompY"); +const static TCHAR* pszECDSA_PRIVATE_KEY = _T("ECDSA_Private_Key"); +const static TCHAR* pszEND_ECDSA_PRIVATE_KEY = _T("End_ECDSA_Private_Key"); + + +const static TCHAR* pszEND_EXT_RSV_DATA = _T("End_Extended_Reserved_Data"); +const static TCHAR* pszCLK_ENABLE = _T("Clock_Enable"); +const static TCHAR* pszEND_CLK_ENABLE = _T("End_Clock_Enable"); +const static TCHAR* pszDDR_GEO = _T("DDR_Geometry"); +const static TCHAR* pszEND_DDR_GEO = _T("End_DDR_Geometry"); +const static TCHAR* pszDDR_TIMING = _T("DDR_Timing"); +const static TCHAR* pszEND_DDR_TIMING = _T("End_DDR_Timing"); +const static TCHAR* pszDDR_CUSTOM = _T("DDR_Custom"); +const static TCHAR* pszEND_DDR_CUSTOM = _T("End_DDR_Custom"); +const static TCHAR* pszFREQ = _T("Frequency"); +const static TCHAR* pszEND_FREQ = _T("End_Frequency"); +const static TCHAR* pszVOL = _T("Voltages"); +const static TCHAR* pszEND_VOL = _T("End_Voltages"); +const static TCHAR* pszCFG_MEM_CTRL = _T("Configure_Memory_Control"); +const static TCHAR* pszEND_CFG_MEM_CTRL = _T("End_Configure_Memory_Control"); +const static TCHAR* pszTRUST_Z = _T("Trust_Zone"); +const static TCHAR* pszEND_TRUST_Z = _T("End_Trust_Zone"); +const static TCHAR* pszTRUST_Z_RE = _T("Trust_Zone_Regid"); +const static TCHAR* pszEND_TRUST_Z_RE = _T("End_Trus_Zone_Regid"); +const static TCHAR* pszOPDIV = _T("OpDiv"); +const static TCHAR* pszEND_OPDIV = _T("End_OpDiv"); +const static TCHAR* pszOPMOD = _T("OpMode"); +const static TCHAR* pszEND_OPMOD = _T("End_OpMode"); +const static TCHAR* pszERDVEC = _T("ErdVec"); +const static TCHAR* pszEND_ERDVEC = _T("End_ErdVec"); + +const static TCHAR* pszTR069_INFO = _T("TRFU"); +const static TCHAR* pszTR069_ENABLED = _T("Enabled"); +const static TCHAR* pszTR069_FLASH_ADDR = _T("Flash_Address"); +const static TCHAR* pszTR069_MAGIC = _T("Magic"); +const static TCHAR* pszTR069_INFO_END = _T("End_TRFU"); + +const static TCHAR* pszFOTA_INFO = _T("OTAI"); +const static TCHAR* pszFOTA_ENABLED = _T("Enabled"); +const static TCHAR* pszFOTA_FLASH_ADDR = _T("Flash_Address"); +const static TCHAR* pszFOTA_MAGIC = _T("Magic"); +const static TCHAR* pszFOTA_INFO_END = _T("End_OTAI"); + +const static TCHAR* pszDDR_TYPE_BEGIN = _T("DTYP"); +const static TCHAR* pszDDR_TYPE_VALUE = _T("DDR_Type"); +const static TCHAR* pszDDR_TYPE_END = _T("End_DTYP"); + +const static TCHAR* pszDDR_BYTE_SELECT_BEGIN = _T("DDBS"); +const static TCHAR* pszDDR_BYTE_SELECT = _T("DDR_Byte_Select"); +const static TCHAR* pszDDR_BYTE_SELECT_END = _T("End_DDBS"); + + +//LTG LWG SELECT PACKAGE +const static TCHAR* pszLTG_LWG_SELECT_BEGIN = _T("LTWS"); +const static TCHAR* pszLTG_LWG_SELECT_VALUE = _T("LTG_LWG_Select"); +const static TCHAR* pszLTG_LWG_SELECT_END = _T("End_LTWS"); + +const static TCHAR* pszCUSTOMER_TRANSFER_INFO = _T("CITA_CUMIZED_INFO_TRANSFER_TOAP_ID"); +const static TCHAR* pszCUSTOMER_TRANSFER_INFO_END = _T("End_CITA_CUMIZED_INFO_TRANSFER_TOAP_ID"); + +const static TCHAR* pszBBMIDTYPE = _T("BBMT"); +const static TCHAR* pszBBMIDTYPE_END = _T("End_BBMT"); + +const static TCHAR* pszFLASHGEOPKGID = _T("FGPI"); +const static TCHAR* pszFLASHGEOPKGID_END = _T("End_FGPI"); + +const static TCHAR* pszBBCS_BEGIN = _T("BBCS"); +const static TCHAR* pszBBCS_VALUE = _T("Enabled"); +const static TCHAR* pszBBCS_END = _T("End_BBCS"); + +const static TCHAR* pszCRCS_BEGIN = _T("CRCS"); +const static TCHAR* pszCRCS_VALUE = _T("Enabled"); +const static TCHAR* pszCRCS_END = _T("End_CRCS"); + +// Added by ZQQ to support DTIM 2012-03-28 +const static TCHAR* pszDTIM_KEYS_DATA = _T("DTIM_Keys_Data"); +const static TCHAR* pszEND_DTIM_KEYS_DATA = _T("End_DTIM_Keys_Data"); + +const static TCHAR* pszPRODUCTION_MODE = _T("ProductionMode"); + +const static TCHAR* pszDDR_FLASH_MCP_MAP = _T("DDR_Flash_Mcp_Map"); +const static TCHAR* pszEND_DDR_FLASH_MCP_MAP = _T("End_DDR_Flash_Mcp_Map"); + +// definition for PXA92x +//Added by zqq 2012-2-3 + +const static TCHAR* pszPXA92x_TIM_CFG = _T("TIM Configuration"); +const static TCHAR* pszPXA92x_SKIP_BLOCK_CFG = _T("Skip Block Configuration"); +const static TCHAR* pszPXA92x_TRUSTED = _T("Trusted"); +const static TCHAR* pszPXA92x_TOTAL_SKIPBLOCK = _T("Total Skip Block Numbers"); +const static TCHAR* pszPXA92x_SKIP_BLOCK_NUMBER = _T("Skip Block Number"); +const static TCHAR* pszPXA92x_ERASE_ALL_FLASH = _T("Erase All Flash"); +const static TCHAR* pszPXA92x_FLASHER_ADRES = _T("FlasherLoadAddress"); +const static TCHAR* pszPXA92x_VERSION = _T("Version"); +const static TCHAR* pszPXA92x_ISSUDT = _T("Issue Date"); +const static TCHAR* pszPXA92x_OEMUID = _T("OEM UniqueID"); +const static TCHAR* pszPXA92x_PROCESSOR_TYPE = _T("Processor Type"); +const static TCHAR* pszPXA92x_BOOT_FLASH_SIG = _T("Boot Flash Signature"); +const static TCHAR* pszPXA92x_SIZE_OF_IMG = _T("Number of Images"); +const static TCHAR* pszPXA92x_SIZE_OF_RSV = _T("Size of Reserved in bytes"); +const static TCHAR* pszPXA92x_NUM_OF_KEYS = _T("Number of Keys"); +const static TCHAR* pszPXA92x_EXT_RSV_DATA = _T("Extended Reserved Data"); +const static TCHAR* pszPXA92x_END_EXT_RSV_DATA = _T("End Extended Reserved Data"); +const static TCHAR* pszPXA92x_RSV_DATA = _T("[Reserved Data]"); +const static TCHAR* pszPXA92x_END_RSV_DATA = _T("End Reserved Data"); +const static TCHAR* pszPXA92x_WTM_FL_SIGTURE = _T("WTM Save State Flash Signature"); +const static TCHAR* pszPXA92x_WTM_FL_EN_ADDR = _T("WTM Save State Flash Entry Address"); +const static TCHAR* pszPXA92x_WTM_BK_EN_ADDR = _T("WTM Save State BackUp Entry Address"); + + +const static TCHAR* pszPXA92x_FL_PATH = _T("Flasher Path"); +const static TCHAR* pszPXA92x_AUTH_PATH = _T("Authentication Path"); +const static TCHAR* pszPXA92x_JTAG_TIM_PATH = _T("Jtag TIM File Path"); +const static TCHAR* pszPXA92x_ST_ADDR = _T("Start Address"); +const static TCHAR* pszPXA92x_IMEI_PATH = _T("IMEI File Path"); +const static TCHAR* pszPXA92x_MEP_PATH = _T("MEP File Path"); +const static TCHAR* pszPXA92x_IMG_LIST = _T("Image List"); +const static TCHAR* pszPXA92x_ENBL = _T("Enable"); +const static TCHAR* pszPXA92x_PATH = _T("Path"); +const static TCHAR* pszPXA92x_FL_ENTRY_ADDR = _T("Flash Entry Address"); +const static TCHAR* pszPXA92x_LOAD_ADDR = _T("Load Address"); +const static TCHAR* pszPXA92x_SIZE_OF_IMGTOCRC = _T("Image Size To CRC in bytes"); +const static TCHAR* pszPXA92x_SIZE_OF_IMGTOHASH = _T("Image Size To Hash in bytes"); +const static TCHAR* pszPXA92x_SIZE_OF_ERASE = _T("Erase Size"); + + +const static TCHAR* pszPXA92x_PARTITION = _T("Partition Number"); +const static TCHAR* pszPXA92x_IMGID_NAME = _T("ID Name"); +const static TCHAR* pszPXA92x_IMGID = _T("Image ID"); +const static TCHAR* pszPXA92x_NTIMGID = _T("Next Image ID"); +const static TCHAR* pszPXA92x_HASH_ALGT_ID = _T("Hash Algorithm ID"); +const static TCHAR* pszPXA92x_OFST = _T("Offset"); +const static TCHAR* pszPXA92x_TYPE = _T("Type"); +const static TCHAR* pszPXA92x_OLD_FLASHER = _T("Flasher Property"); +const static TCHAR* pszPXA92x_FLASH_PROP = _T("Flash Properties"); +const static TCHAR* pszPXA92x_CFG_FILE_PATH = _T("Flash Configuration File Path"); +const static TCHAR* pszPXA92x_TAVOR_PROP = _T("Tavor Flasher Properties"); +const static TCHAR* pszPXA92x_NONE_ERASESIZE = _T(""); +const static TCHAR* pszPXA92x_SPARE_SIZE = _T("Spare Area Size"); +const static TCHAR* pszPXA92x_DATA_SIZE = _T("Data Area Size"); + +const static TCHAR* pszPXA92x_JTAG_TRUSTED = _T("JTAG TRUSTED"); +const static TCHAR* pszPXA92x_JTAG_TIM = _T("TIM Path"); +const static TCHAR* pszPXA92x_JTAG_KEY = _T("KEY Path"); + +const static TCHAR* pszPXA92x_ERASE_ALL = _T("Erase All"); +const static TCHAR* pszPXA92x_END_ERASE_ALL = _T("End Erase All"); +const static TCHAR* pszPXA92x_CLK_ENABLE = _T("Clock Enable"); +const static TCHAR* pszPXA92x_END_CLK_ENABLE = _T("End Clock Enable"); +const static TCHAR* pszPXA92x_DDR_GEO = _T("DDR Geometry"); +const static TCHAR* pszPXA92x_END_DDR_GEO = _T("End DDR Geometry"); +const static TCHAR* pszPXA92x_DDR_TIMING = _T("DDR Timing"); +const static TCHAR* pszPXA92x_END_DDR_TIMING = _T("End DDR Timing"); +const static TCHAR* pszPXA92x_DDR_CUSTOM = _T("DDR Custom"); +const static TCHAR* pszPXA92x_END_DDR_CUSTOM = _T("End DDR Custom"); +const static TCHAR* pszPXA92x_FREQ = _T("Frequency"); +const static TCHAR* pszPXA92x_END_FREQ = _T("End Frequency"); +const static TCHAR* pszPXA92x_VOL = _T("Voltages"); +const static TCHAR* pszPXA92x_END_VOL = _T("End Voltages"); +const static TCHAR* pszPXA92x_CFG_MEM_CTRL = _T("Configure Memory Control"); +const static TCHAR* pszPXA92x_END_CFG_MEM_CTRL = _T("End Configure Memory Control"); +const static TCHAR* pszPXA92x_TRUST_Z = _T("Trust Zone"); +const static TCHAR* pszPXA92x_END_TRUST_Z = _T("End Trust Zone"); +const static TCHAR* pszPXA92x_TRUST_Z_RE = _T("Trust Zone Regid"); +const static TCHAR* pszPXA92x_END_TRUST_Z_RE = _T("End Trust Zone Regid"); +const static TCHAR* pszPXA92x_OPDIV = _T("OpDiv"); +const static TCHAR* pszPXA92x_END_OPDIV = _T("End OpDiv"); +const static TCHAR* pszPXA92x_OPMOD = _T("OpMode"); +const static TCHAR* pszPXA92x_END_OPMOD = _T("End OpMode"); +const static TCHAR* pszPXA92x_ERDVEC = _T("ErdVec"); +const static TCHAR* pszPXA92x_END_ERDVEC = _T("End ErdVec"); +const static TCHAR* pszPXA92x_DEVICE_USB_MAP = _T("DEVICE_USBPORT_MAP"); +const static TCHAR* pszPXA92x_DEVICE_USBPORT_NUMBER = _T("MAX Device USB Port Number"); +const static TCHAR* pszPXA92x_DEVICE_USB_PORT = _T("Device USB Port"); +const static TCHAR* pszPXA92x_ERASE_ONLY = _T("Erase only Area"); +const static TCHAR* pszPXA92x_ERASE_ONLY_NUM = _T("Erase Area Num"); +const static TCHAR* pszPXA92x_ERASE_ONLY_START_ADD = _T("Erase Flash Start Address"); +const static TCHAR* pszPXA92x_ERASE_ONLY_LENGTH = _T("Erase Length"); +const static TCHAR* pszPXA92x_ERASE_ONLY_PARTITION = _T("Erase Area Partition"); +const static TCHAR* pszPXA92x_DEV_HEADER_0 = _T("DEV_HEADER_0"); +const static TCHAR* pszPXA92x_BLOCK_SIZE_NAME = _T("Block_Size_0"); +const static TCHAR* pszPXA92x_FLASHFAMLIY = _T("FlashFamily"); +const static TCHAR* pszPXA92x_FLASHINI = _T("INTEL_FLASHER_INPUT_FILE"); +const static TCHAR* pszPXA92x_FLASH_BLOCKS = _T("Number_of_Blocks_0"); + + + + +const static TCHAR* pszUPLOAD_PROPERTY = _T("Upload_Property"); +const static TCHAR* pszMAX_UPLOAD_SIZE = _T("Max_Upload_Size"); +const static TCHAR* pszUPLOADAREA_NUM = _T("Upload_Area_Nums"); +const static TCHAR* pszUPLOAD_RESETUE = _T("ResetUE_AfterUpload"); +const static TCHAR* pszUPLOAD_TIMEDELAY_RESET = _T("Reset_DelayTime"); +const static TCHAR* pszUPLOADAREA_LIST = _T("Upload_Areas_List"); +const static TCHAR* pszUPLOADAREA_TYPE = _T("Area_Type"); +const static TCHAR* pszUPLOADAREA_SUBTYPE = _T("Area_SubType"); +const static TCHAR* pszUPLOADAREA_OFFSET = _T("Area_Offset"); +const static TCHAR* pszUPLOADAREA_DATATSIZE = _T("Area_DataSize"); +const static TCHAR* pszUPLOADAREA_PARTITION = _T("Area_Partition"); +const static TCHAR* pszUPLOADAREA_SPAREAREA = _T("Area_UploadWithSpareArea"); +const static TCHAR* pszUPLOADAREA_SAVEFILE = _T("Area_UploadData_SaveFile"); +const static TCHAR* pszBLFVERSION = _T("Blf_Version"); +const static TCHAR* pszFlashFamily = _T("Flash_Family"); +const static TCHAR* pszPlatFormType = _T("PlatForm_Type"); + +const static TCHAR* pszEMMCIMAGEPROPERTY = _T("EMMC_Images_list_Property"); +const static TCHAR* pszEMMCIMGIDNUM = _T("ImageID_num"); +const static TCHAR* pszEMMCTYPECFG = _T("EmmcType"); + +//mutliple Nand size +const static TCHAR* pszNAND_SIGNATURE_NUMBER = _T("Nand_Signature_Number"); +const static TCHAR* pszNAND_IMAGE_PROPERTY = _T("Nand_Images_list_Property"); +const static TCHAR* pszNANDSIGN = _T("NandSign"); +const static TCHAR* pszNANDSIGN_VALUE = _T("NandSign_Value"); +const static TCHAR* pszNANDSIGN_NANDIDNUMBER = _T("NandSign_NandIdNumber"); +const static TCHAR* pszNANDID = _T("NandId"); +const static TCHAR* pszNANDSIZE = _T("NandSize"); +const static TCHAR* pszIMAGENUMBER = _T("ImageNumber"); + +//#define pszNAND_SIGNATURE_NUMBER _T("NAND_Signature_Number") +//#define pszNAND_IMAGE_PROPERTY _T("NAND_Images_list_Property") +//#define pszNANDSIGN _T("NandSign") +//#define pszNANDSIGN_VALUE _T("NandSign_Value") +//#define pszNANDSIGN_NANDIDNUMBER _T("NandSign_NandIdNumber") +//#define pszNANDID _T("NandId") +//#define pszNANDSIZE _T("NandSize") +//#define pszIMAGENUMBER _T("ImageNumber") + + + + + + + + + + + + + + + + +#define MAX_DDR_VENDOR_NUM 34 +#define MAX_DDR_SIZE_NUM 20 + +struct stDdrVendorIdNameMap{ + unsigned int nDdrVendorID; + TCHAR strDdrVendorName[128]; +}; + +static const struct stDdrVendorIdNameMap vendorDdrPidNameMap[MAX_DDR_VENDOR_NUM]={ + {0x01,_T("SAMSUNG")}, + {0x02,_T("QIMONDA")}, + {0x03,_T("ELPIDA")}, + {0x04,_T("ETRON")}, + {0x05,_T("NANYA")}, + {0x06,_T("HYNIX")}, + {0x07,_T("MOSEL")}, + {0x08,_T("WINBOND")}, + {0x09,_T("ESMT")}, + {0x0A,_T("RESERVED")}, + {0x0B,_T("SPANSION")}, + {0x0C,_T("SST")}, + {0x0D,_T("ZMOS")}, + {0x0E,_T("INTEL")}, + {0x0F,_T("NUMONYX")}, + {0x10,_T("MICRON")}, + {0x11,_T("TOSHIBA")}, + {0x12,_T("FIDELIX")}, + {0x13,_T("ReservedVendor1")}, + {0x14,_T("ReservedVendor2")}, + {0x15,_T("ReservedVendor3")}, + {0x16,_T("ReservedVendor4")}, + {0x17,_T("ReservedVendor5")}, + {0x18,_T("ReservedVendor6")}, + {0x19,_T("ReservedVendor7")}, + {0x1A,_T("ReservedVendor8")}, + {0x1B,_T("ReservedVendor9")}, + {0x1C,_T("JSC")}, + {0x1D,_T("ReservedVendor11")}, + {0x1E,_T("ReservedVendor12")}, + {0xF8,_T("Fidelix")}, + {0xFD,_T("ESMT2")}, + {0xFE,_T("Numonyx")}, + {0xFF,_T("Micron")}, +}; + + +#define RESERVED_DDR_FOR_SMALLMEMORY 0x300000 /* Reserved 3MB DDR Size for OBM on platform Nezha and Nezha2 */ +#define RESERVED_DDR_FOR_LARGEMEMORY 0x1E00000 /* Reserved 30MB DDR Size for OBM */ +#define UNIT_GB 0x40000000 diff --git a/fbfdownloader/src/BinFileWtp.c b/fbfdownloader/src/BinFileWtp.c new file mode 100644 index 00000000..fd5b3d87 --- /dev/null +++ b/fbfdownloader/src/BinFileWtp.c @@ -0,0 +1,353 @@ +#include "CommonFun.h" +#include "BinFileWtp.h" +#include +#define BINFILE _T("BinFile.bin") + + + +BOOL BinFileWtp_OpenBinFile(struct CBinFileWtp *me, const TCHAR *strOpenMode) +{ + + if (me->m_fBinFile) + BinFileWtp_CloseBinFIle(me); + me->m_fBinFile = _tfopen((const TCHAR *)me->m_strBinFilePath, strOpenMode); + if (NULL == me->m_fBinFile) + { + printf("Open BinFile.bin Failed!\n"); + return FALSE; + } + else + { + printf("Open BinFile.bin Successed!\n"); + return TRUE; + } +} + +UINT32 BinFileWtp_ReadBinFile(struct CBinFileWtp *me, void *buffer, size_t size, size_t count, const TCHAR *pszBinFile) +{ + UINT32 ret = 0; + UINT32 uRemain = 0; + UINT32 uRPos = 0; + khiter_t kfs, kfp; + kfs = kh_get(str2fs, me->m_mapFile2Struct, pszBinFile); + if (kfs == kh_end(me->m_mapFile2Struct)) + return ret; + uRemain = size * count; + kfp = kh_get(str2n, me->m_mapFile2PointPos, pszBinFile); + uRPos = kh_value(me->m_mapFile2PointPos, kfp); + if (0 == kh_value(me->m_mapFile2Struct, kfs).Head2 && 0 == kh_value(me->m_mapFile2Struct, kfs).Mid1 && 0 == kh_value(me->m_mapFile2Struct, kfs).Mid2 && 0 == kh_value(me->m_mapFile2Struct, kfs).Tail1) + { + fseek(me->m_fBinFile, uRPos, SEEK_SET); + ret = fread(buffer, size, count, me->m_fBinFile); + kh_value(me->m_mapFile2PointPos, kfp) += size * count; + } + else //分段读取情况 + { + fseek(me->m_fBinFile, uRPos, SEEK_SET); + if (uRPos >= kh_value(me->m_mapFile2Struct, kfs).Head1 && uRPos < kh_value(me->m_mapFile2Struct, kfs).Head2) + { + if (uRemain < kh_value(me->m_mapFile2Struct, kfs).Head2 - uRPos) + { + ret += fread(buffer, sizeof(BYTE), uRemain, me->m_fBinFile); + kh_value(me->m_mapFile2PointPos, kfp) += uRemain; + uRemain = 0; + } + else + { + ret += fread(buffer, sizeof(BYTE), kh_value(me->m_mapFile2Struct, kfs).Head2 - uRPos, me->m_fBinFile); + uRemain -= (kh_value(me->m_mapFile2Struct, kfs).Head2 - uRPos); + buffer = (void *)((char *)buffer + kh_value(me->m_mapFile2Struct, kfs).Head2 - uRPos); + uRPos = kh_value(me->m_mapFile2Struct, kfs).Mid1; + kh_value(me->m_mapFile2PointPos, kfp) = uRPos; + fseek(me->m_fBinFile, uRPos, SEEK_SET); + } + } + if (uRPos >= kh_value(me->m_mapFile2Struct, kfs).Mid1 && uRPos < kh_value(me->m_mapFile2Struct, kfs).Mid2) + { + if (uRemain < kh_value(me->m_mapFile2Struct, kfs).Mid2 - uRPos) + { + ret += fread(buffer, sizeof(BYTE), uRemain, me->m_fBinFile); + uRPos += uRemain; + kh_value(me->m_mapFile2PointPos, kfp) = uRPos; + uRemain = 0; + } + else + { + ret += fread(buffer, sizeof(BYTE), kh_value(me->m_mapFile2Struct, kfs).Mid2 - uRPos, me->m_fBinFile); + uRemain -= (kh_value(me->m_mapFile2Struct, kfs).Mid2 - uRPos); + buffer = (void *)((char *)buffer + kh_value(me->m_mapFile2Struct, kfs).Mid2 - uRPos); + uRPos = kh_value(me->m_mapFile2Struct, kfs).Tail1; + kh_value(me->m_mapFile2PointPos, kfp) = uRPos; + fseek(me->m_fBinFile, uRPos, SEEK_SET); + } + } + if (uRPos >= kh_value(me->m_mapFile2Struct, kfs).Tail1 && uRPos < kh_value(me->m_mapFile2Struct, kfs).Tail2) + { + ret += fread(buffer, sizeof(BYTE), uRemain, me->m_fBinFile); + kh_value(me->m_mapFile2PointPos, kfp) += uRemain; + uRemain = 0; + } + } + return ret; +} + +int BinFileWtp_FseekBin(struct CBinFileWtp *me, const TCHAR *pszBinFile, long _Offset, int _Origin) +{ + int ret; + khint_t kfs, kfp; + kfp = kh_get(str2n, me->m_mapFile2PointPos, pszBinFile); + kfs = kh_get(str2fs, me->m_mapFile2Struct, pszBinFile); + if (kfp == kh_end(me->m_mapFile2PointPos) || kfs == kh_end(me->m_mapFile2Struct)) + return -1; + if (SEEK_SET == _Origin) + { + ret = fseek(me->m_fBinFile, kh_value(me->m_mapFile2Struct, kfs).Head1 + _Offset, SEEK_SET); + kh_value(me->m_mapFile2PointPos, kfp) = kh_value(me->m_mapFile2Struct, kfs).Head1 + _Offset; + } + else if (SEEK_END == _Origin) + { + ret = fseek(me->m_fBinFile, kh_value(me->m_mapFile2Struct, kfs).Tail2 + _Offset, SEEK_SET); + kh_value(me->m_mapFile2PointPos, kfp) = kh_value(me->m_mapFile2Struct, kfs).Tail2 + _Offset; + } + else + { + fseek(me->m_fBinFile, kh_value(me->m_mapFile2PointPos, kfp) + _Offset, SEEK_SET); + } + return ret; +} + +UINT32 BinFileWtp_GetFileSize(struct CBinFileWtp *me, const TCHAR *pszBinFile) +{ + khiter_t kfs; + kfs = kh_get(str2fs, me->m_mapFile2Struct, pszBinFile); + if (kh_end(me->m_mapFile2Struct) == kfs) + return 0; + else + { + return kh_value(me->m_mapFile2Struct, kfs).Head2 - kh_value(me->m_mapFile2Struct, kfs).Head1 + kh_value(me->m_mapFile2Struct, kfs).Mid2 - kh_value(me->m_mapFile2Struct, kfs).Mid1 + kh_value(me->m_mapFile2Struct, kfs).Tail2 - kh_value(me->m_mapFile2Struct, kfs).Tail1; + } +} + +void BinFileWtp_CloseBinFIle(struct CBinFileWtp *me) +{ + if (NULL != me->m_fBinFile) + { + fclose(me->m_fBinFile); + me->m_fBinFile = NULL; + } +} + +void BinFileWtp_FreshBinOffset(struct CBinFileWtp *me) +{ + fseek(me->m_fBinFile, 0, SEEK_END); + me->m_uFileOffset = ftell(me->m_fBinFile); +} + +void BinFileWtp_ResetPara(struct CBinFileWtp *me) +{ + me->m_bHaveInitForFbfDown = FALSE; + me->m_uFileOffset = 0; + me->m_fBinFile = NULL; + if (me->m_mapFile2PointPos) + kh_destroy(str2n, me->m_mapFile2PointPos); + if (me->m_mapFile2Struct) + kh_destroy(str2fs, me->m_mapFile2Struct); + me->m_mapFile2PointPos = kh_init(str2n); + me->m_mapFile2Struct = kh_init(str2fs); +} + +void BinFileWtp_InitRead(struct CBinFileWtp *me) +{ + khiter_t kfs, kfp; + int ret; + for (kfs = kh_begin(me->m_mapFile2Struct); kfs != kh_end(me->m_mapFile2Struct); ++kfs) + if (kh_exist(me->m_mapFile2Struct, kfs)) + { + kfp = kh_put(str2n, me->m_mapFile2PointPos, kh_key(me->m_mapFile2Struct, kfs), &ret); + kh_value(me->m_mapFile2PointPos, kfp) = kh_value(me->m_mapFile2Struct, kfs).Head1; + } +} + +void BinFileWtp_InitParameter(struct CBinFileWtp *me) +{ + TCHAR buffer[1024]; + khiter_t kfp, kfs; + char *pstr; + int ret; + if (me->m_bHaveInitForFbfDown) + return; + BinFileWtp_ResetPara(me); +#if !defined(LINUX) + memset(me->m_strBinFilePath, 0x00, sizeof(me->m_strBinFilePath)); + tsnprintf(me->m_strBinFilePath, sizeof(me->m_strBinFilePath), _T("%s\\temp\\%s"), (pstr = GetAppPath().s), BINFILE); + free(pstr); +#else + memset(me->m_strBinFilePath, 0x00, sizeof(me->m_strBinFilePath)); + tsnprintf(me->m_strBinFilePath, sizeof(me->m_strBinFilePath), _T("%s/temp/%s"), (pstr = GetAppPath().s), BINFILE); + free(pstr); +#endif + + UINT32 uValue; + BinFileWtp_OpenBinFile(me, _T("rb")); + fseek(me->m_fBinFile, -1L * sizeof(UINT32), SEEK_END); + //读FBF文件最后的偏移,之后的为map信息 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + printf("Read from File Value is %x\n", uValue); + uValue = le32toh(uValue); + printf("After Convert Value is %x\n", uValue); + fseek(me->m_fBinFile, uValue, SEEK_SET); + //读map size + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + unsigned int i = uValue; + while (i) + { + i--; + memset(buffer, 0, sizeof(buffer)); + //读路径文件长度 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + //读路径文件 + uValue = le32toh(uValue); + fread(buffer, 1, uValue, me->m_fBinFile); + kfs = kh_put(str2fs, me->m_mapFile2Struct, buffer, &ret); + kfp = kh_put(str2n, me->m_mapFile2PointPos, buffer, &ret); + //读Head1 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Head1 = uValue; + kh_value(me->m_mapFile2PointPos, kfp) = uValue; + //读Head2 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Head2 = uValue; + //读Mid1 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Mid1 = uValue; + //读Mid2 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Mid2 = uValue; + //读Tail1 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Tail1 = uValue; + //读Tail2 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Tail2 = uValue; + } +} +BOOL BinFileWtp_InitParameter2(struct CBinFileWtp *me, const TCHAR *pBinFilePath, struct StringList *pFbfList) +{ + TCHAR buffer[1024]; + int ret, nPosBuf; + khiter_t kfp, kfs; + if (me->m_bHaveInitForFbfDown) + return TRUE; + BinFileWtp_ResetPara(me); + me->m_bHaveInitForFbfDown = TRUE; + +#if !defined(LINUX) + memset(me->m_strBinFilePath, 0x00, sizeof(me->m_strBinFilePath)); + tsnprintf(me->m_strBinFilePath, sizeof(me->m_strBinFilePath), _T("%s"), pBinFilePath); +#else + memset(me->m_strBinFilePath, 0x00, sizeof(me->m_strBinFilePath)); + tsnprintf(me->m_strBinFilePath, sizeof(me->m_strBinFilePath), _T("%s"), pBinFilePath); +#endif + + UINT32 uValue = 0; + if (FALSE == BinFileWtp_OpenBinFile(me, _T("rb"))) + { + return FALSE; + } + fseek(me->m_fBinFile, -1L * sizeof(UINT32), SEEK_END); + //读FBF文件最后的偏移,之后的为map信息 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + printf("Read from File Value is %x\n", uValue); + uValue = le32toh(uValue); + printf("Convert Value is %x\n", uValue); + fseek(me->m_fBinFile, uValue, SEEK_SET); + printf("Offset of Map is %u\n", uValue); + //读map size + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + printf("Size of Map is %u\n", uValue); + unsigned int i = uValue; + + while (i) + { + i--; + memset(buffer, 0, sizeof(buffer)); + //读路径文件长度 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + //读路径文件 + fread(buffer, 1, uValue, me->m_fBinFile); +#ifndef UNICODE + nPosBuf = 0; + for (int j = 0; j < uValue; j++) + { + if (buffer[j] != 0) + { + buffer[nPosBuf] = buffer[j]; + ++nPosBuf; + } + buffer[nPosBuf] = 0; + } +#endif + const char *buf2 = strdup(buffer); + printf("Find image name:%s\n", buf2); + kfp = kh_put(str2n, me->m_mapFile2PointPos, buf2, &ret); + kfs = kh_put(str2fs, me->m_mapFile2Struct, buf2, &ret); + + //读Head1 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Head1 = uValue; + kh_value(me->m_mapFile2PointPos, kfp) = uValue; + + //读Head2 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Head2 = uValue; + //读Mid1 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Mid1 = uValue; + //读Mid2 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Mid2 = uValue; + //读Tail1 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Tail1 = uValue; + //读Tail2 + fread(&uValue, sizeof(UINT32), 1, me->m_fBinFile); + uValue = le32toh(uValue); + kh_value(me->m_mapFile2Struct, kfs).Tail2 = uValue; + pFbfList->strL[pFbfList->nSize++] = buf2; + } + return TRUE; +} + +BOOL BinFileWtp_IsFileExist(struct CBinFileWtp *me, const TCHAR *pFileName) +{ + khiter_t k; + k = kh_get(str2fs, me->m_mapFile2Struct, pFileName); + if (k == kh_end(me->m_mapFile2Struct)) + return FALSE; + else + return TRUE; +} + +void BinFileWtp_DelMe(struct CBinFileWtp *me) +{ + khiter_t k; + for (k = kh_begin(me->m_mapFile2PointPos); k != kh_end(me->m_mapFile2PointPos); ++k) + if (kh_exist(me->m_mapFile2PointPos, k)) + { + free((void *)kh_key(me->m_mapFile2PointPos, k)); + } +} diff --git a/fbfdownloader/src/BinFileWtp.h b/fbfdownloader/src/BinFileWtp.h new file mode 100644 index 00000000..3c556d82 --- /dev/null +++ b/fbfdownloader/src/BinFileWtp.h @@ -0,0 +1,51 @@ +#pragma once + +#include "Macrodef.h" +#include "ApplicationINI.h" +#include "ParaDefine.h" +#include +#include +#include "khash.h" +#include "klist.h" + +typedef struct _FileStruct +{ + UINT32 Head1, Head2; + UINT32 Mid1, Mid2; + UINT32 Tail1, Tail2; +} FileStruct; + +KHASH_MAP_INIT_STR(str2n,UINT32) +KHASH_MAP_INIT_STR(str2fs,FileStruct) +#define BINFILE _T("BinFile.bin") + + +typedef khash_t(str2n) *t_FilePathWriteOffsetMap; + +typedef khash_t(str2fs)* t_FileNameFileStructMap; + +BOOL BinFileWtp_OpenBinFile(struct CBinFileWtp *me,const TCHAR* strOpenMode); +UINT32 BinFileWtp_ReadBinFile(struct CBinFileWtp *me,void *buffer, size_t size, size_t count, const TCHAR* pszBinFile); +int BinFileWtp_FseekBin(struct CBinFileWtp *me,const TCHAR* pszBinFile,long _Offset,int _Origin); +BOOL BinFileWtp_IsFileExist(struct CBinFileWtp *me,const TCHAR *pFileName); +UINT32 BinFileWtp_GetFileSize(struct CBinFileWtp *me,const TCHAR* pszBinFile); +BOOL BinFileWtp_InitParameter2(struct CBinFileWtp *me,const TCHAR *pBinFilePath, struct StringList*); +void BinFileWtp_InitParameter(struct CBinFileWtp *me); +void BinFileWtp_CloseBinFIle(struct CBinFileWtp *me); +void BinFileWtp_FreshBinOffset(struct CBinFileWtp *me); +void BinFileWtp_ResetPara(struct CBinFileWtp *me); +void BinFileWtp_InitRead(struct CBinFileWtp *me); +void BinFileWtp_DelMe(struct CBinFileWtp *me); + + +struct CBinFileWtp +{ + FILE* m_fBinFile; + t_FileNameFileStructMap m_mapFile2Struct; + t_FilePathWriteOffsetMap m_mapFile2PointPos;//文件指针位置 相对起始 + UINT32 m_uFileOffset;//Bin文件总偏移 + TCHAR m_strBinFilePath[MAX_FILE_LENGTH]; + BOOL m_bHaveInitForFbfDown; +}; + +extern struct CBinFileWtp gBinFileWtp; diff --git a/fbfdownloader/src/BulkDevNonDrv_Linux.c b/fbfdownloader/src/BulkDevNonDrv_Linux.c new file mode 100644 index 00000000..3162e345 --- /dev/null +++ b/fbfdownloader/src/BulkDevNonDrv_Linux.c @@ -0,0 +1,710 @@ +#include "BulkDevNonDrv_Linux.h" + +#define MAX_RETRIES 5 + + +int BulkDevNonDrv_check(void *_desc, int nLen, unsigned int type, int size) +{ + unsigned char *desc = (unsigned char *)_desc; + + if(nLen < size) return 0; + if(desc[0] < size) return 0; + if(desc[0] > nLen) return 0; + if(desc[1] != type) return 0; + + return 1; +} + +int BulkDevNonDrv_badname(const char *name) +{ + while(*name) + { + if(!isdigit(*name++)) + return 1; + } + + return 0; +} + +int BulkDevNonDrv_OpenDev(USB_HANDLE *usb) +{ + char DevDesc[1024]; + int bRet = 0; + int hDevHandle = 0; + int nLen = 0; + int PipeIn = -1; + int PipeOut = -1; + int ifc_id = -1; + +#ifdef __ANDROID__ + chmod(usb->DevName,0777); +#endif + +#if 0 + char szBuffer[MAX_FILE_LENGTH]; + memset(szBuffer,0,sizeof(Tchar)*MAX_FILE_LENGTH); + snprintf(szBuffer,sizeof(szBuffer),("su -c \"chmod -R 777 /dev/bus/usb/\"")); + int r = system(szBuffer); + + if(r!=0) { + printf("Could not grant permissions to USB\n"); + } +#endif + + if((hDevHandle = open(usb->DevName, O_RDWR)) >= 0) + { +#if PRINTLOG + printf("Open dev OK\n"); +#endif + system("echo ---open usb OK--- > /dev/kmsg"); + nLen = read(hDevHandle, DevDesc, sizeof(DevDesc)); + if( BulkDevNonDrv_GetPipeOfDev(DevDesc, nLen, &PipeIn, &PipeOut, &ifc_id) ) + { + //printf("GetPipeOfWTPTP OK!\n"); + nLen = ioctl(hDevHandle, USBDEVFS_CLAIMINTERFACE, &ifc_id); + if(nLen == 0) + { +#if PRINTLOG + printf("Check ifc_id OK!\n"); +#endif + system("echo ---claim usb OK--- > /dev/kmsg"); + bRet = 1; + usb->nPipeIn = PipeIn; + usb->nPipeOut = PipeOut; + usb->hDevHandle = hDevHandle; +#if PRINTLOG + printf("DevName is %s, PipeIn is %d, PipeOut is %d, hDevHandle is 0x%X\n", usb->DevName, usb->nPipeIn, usb->nPipeOut, usb->hDevHandle); +#endif + } + else + { + system("echo ---claim usb FAIL--- > /dev/kmsg"); +#if PRINTLOG + printf("Check ifc_id fail! nLen: %d, errno(%d): %s\n", nLen, errno, strerror(errno)); +#endif + close(hDevHandle); + } + } +#if PRINTLOG + else + printf("GetPipeOfWTPTP fail!\n"); +#endif + } + else + { + system("echo ---open usb FAIL--- > /dev/kmsg"); +#if PRINTLOG + printf("Open dev fail, hDevHandle=0x%X\n", hDevHandle); +#endif + } + + return bRet; +} + +int BulkDevNonDrv_CloseDev(USB_HANDLE *usb) +{ + int hDevHandle; + + hDevHandle = usb->hDevHandle; + if(hDevHandle >= 0) + { + close(hDevHandle); +#if PRINTLOG + printf("WTPTP dev: %s was closed!\n", usb->DevName); +#endif + + memset(usb->DevName, 0, 256); + usb->hDevHandle = -1; + usb->nPipeIn = -1; + usb->nPipeOut = -1; + + return 1; + } + return 0; + +} + +int BulkDevNonDrv_WaitDev() +{ + struct sockaddr_nl client; + struct timeval tv; + int CppLive, rcvlen, ret; + fd_set fds; + int buffersize = 2048; + + CppLive = socket(AF_NETLINK, SOCK_RAW, NETLINK_KOBJECT_UEVENT); + memset(&client, 0, sizeof(client)); + client.nl_family = AF_NETLINK; + client.nl_pid = getpid(); + client.nl_groups = 1; + + setsockopt(CppLive, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); + bind(CppLive, (struct sockaddr*)&client, sizeof(client)); + + //while(1) + { + char buff[2048] = {0}; + FD_ZERO(&fds); + FD_SET(CppLive, &fds); + tv.tv_sec = 0; + tv.tv_usec = 100 * 1000; + + ret = select(CppLive+1, &fds, NULL, NULL, &tv); + //if(ret<0) + // continue; + + //if(!(ret>0 && FD_ISSET(CppLive, &fds))) + // continue; + + rcvlen = recv(CppLive, &buff, sizeof(buff), 0); + if(rcvlen>0) + { + for(int nIndex=0; nIndexd_name)) + continue; + + sprintf(busname, "%s/%s", base, de->d_name); + devdir = opendir(busname); + if( 0 == devdir ) + continue; + + while( de = readdir(devdir) ) + { + if(BulkDevNonDrv_badname(de->d_name)) + { + continue; + } + + int nBuffLen = sprintf(devname, "%s/%s", busname, de->d_name); + if( ( hDevHandle = open(devname, O_RDWR) ) >= 0 ) + { + //printf("Opened %s\n", devname); + DevDesc = OrigiPtr; + nBuffLen = read(hDevHandle, DevDesc, 1024); + if( !BulkDevNonDrv_check( DevDesc, nBuffLen, USB_DT_DEVICE, USB_DT_DEVICE_SIZE ) ) + continue; + + dev = (struct usb_device_descriptor *)DevDesc; + nBuffLen -= dev->bLength; + DevDesc += dev->bLength; + + if( BulkDevNonDrv_ChecHWIds2(dev->idVendor, dev->idProduct) ) + { + if( !BulkDevNonDrv_check( DevDesc, nBuffLen, USB_DT_CONFIG, USB_DT_CONFIG_SIZE ) ) + continue; + + info.serial_number[0] = 0; + if(dev->iSerialNumber) + { + struct usbdevfs_ctrltransfer ctrl; + __u16 buffer[128]; + __u16 preCheck[128]; + int nPreCheckCount = 0; + int result; + + memset(buffer, 0, sizeof(buffer)); + memset(preCheck, 0, sizeof(preCheck)); + memset(&ctrl, 0, sizeof(ctrl)); + + ctrl.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; + ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; + ctrl.wValue = (USB_DT_STRING << 8) | 0; //dev->iSerialNumber; + ctrl.wIndex = 0;//__le16_to_cpu(0x409); + ctrl.wLength = sizeof(preCheck); + ctrl.data = preCheck; + + result = ioctl(hDevHandle, USBDEVFS_CONTROL, &ctrl); + if(result>0) + { + int nLoop; + nPreCheckCount = (result - 2) / 2; + + for( nLoop = 1; nLoop <= nPreCheckCount; nLoop++ ) + { + memset(buffer, 0, sizeof(buffer)); + memset(&ctrl, 0, sizeof(ctrl)); + + ctrl.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE; + ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; + ctrl.wValue = (USB_DT_STRING << 8) | dev->iSerialNumber; + ctrl.wIndex = __le16_to_cpu(preCheck[nLoop]); + ctrl.wLength = sizeof(buffer); + ctrl.data = buffer; + + result = ioctl(hDevHandle, USBDEVFS_CONTROL, &ctrl); + if(result>0) + { + int i = 0; + result /= 2; + for(i=1; ibLength; + DevDesc += cfg->bLength; + + for(int loop=0; loopbNumInterfaces; ) + { + if( !BulkDevNonDrv_check( DevDesc, nBuffLen, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE ) ) + { + nBuffLen -= DevDesc[0]; + DevDesc += DevDesc[0]; + continue; + } + + ifc = (struct usb_interface_descriptor *)DevDesc; + nBuffLen -= ifc->bLength; + DevDesc += ifc->bLength; + + if( BulkDevNonDrv_ChecHWIds(dev->idVendor, dev->idProduct, ifc->bInterfaceNumber) ) + { + USB_HANDLE usb; + strcpy(usb.DevName, devname); + if( 0 == strlen(info.serial_number) ) + { + strcpy(usb.iSerialNumber, "None"); + } + else + { + strcpy(usb.iSerialNumber, info.serial_number); + } + hUSBArray[nIndex] = (PUSB_HANDLE)malloc(sizeof(USB_HANDLE)); + NEW_USB_HANDLE(hUSBArray[nIndex]); + COPY_USB_HANDLE(hUSBArray[nIndex],&usb); + nIndex++; + bRet = nIndex; + //printf("Got one supported dev: VID: 0x%X, PID: 0x%X, MI:0x%X\n", dev->idVendor, dev->idProduct, ifc->bInterfaceNumber); + } + loop++; + } + } + close(hDevHandle); + } + + //if(IsSupported(devname, nBuffLen, DevName, nDevNameLen, bAdd)) + // printf("%s\n", devname); + } + closedir(devdir); + } + closedir(busdir); + free(OrigiPtr); + DevDesc = NULL; + OrigiPtr = NULL; + return bRet; +} + +int BulkDevNonDrv_CheckDevForNetLink(USB_HANDLE *usb, const char *NetLinkBuff, int nBuffLen, int *bAdd) +{ + char DevName[256] = {0}; + int nDevNameLen = 0; + int bRet = 0; + + bRet = BulkDevNonDrv_IsSupported(NetLinkBuff, nBuffLen, DevName, &nDevNameLen, bAdd); + if(bRet) + { + strcpy(usb->DevName, DevName); + } + return bRet; +} + +int BulkDevNonDrv_IsSupported(const char *NetLinkBuff, int nBuffLen, char *Dev_Name, int *nDevNameLen, int *bAdd) +{ + int nIndex = 0; + char* position = NULL; + long lVID = 0, lPID = 0; + int bFound = 0; + int bRet = 0; + char tmpNetLinkBuff[4096]; + char* sUSBDescription; + /*AsiaTelco MIPS use proc instead of dev, really strange*/ + //string sDevName = "/proc/"; + char sDevName[512] = "/dev/"; + char sVID[64] = "0x"; + char sPID[64] = "0x"; + + // Prepare the device information buffer + memcpy(tmpNetLinkBuff, NetLinkBuff, nBuffLen); + for(; nIndexbLength; + ptr += dev->bLength; + + if(!BulkDevNonDrv_check(ptr, len, USB_DT_CONFIG, USB_DT_CONFIG_SIZE)) + return 0; + + cfg = (struct usb_config_descriptor *) ptr; + len -= cfg->bLength; + ptr += cfg->bLength; + + //info.dev_vendor = dev->idVendor; + //info.dev_product = dev->idProduct; + //info.dev_class = dev->bDeviceClass; + //info.dev_subclass = dev->bDeviceSubClass; + //info.dev_protocol = dev->bDeviceProtocol; + //info.writable = writable; + + // read device serial number (if there is one) + /*info.serial_number[0] = 0; + if (dev->iSerialNumber) + { + + struct usbdevfs_ctrltransfer ctrl; + __u16 buffer[128]; + int result; + + memset(buffer, 0, sizeof(buffer)); + + ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE; + ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; + ctrl.wValue = (USB_DT_STRING << 8) | dev->iSerialNumber; + ctrl.wIndex = 0; + ctrl.wLength = sizeof(buffer); + ctrl.data = buffer; + + result = ioctl(fd, USBDEVFS_CONTROL, &ctrl); + if (result > 0) + { + int i; + // skip first word, and copy the rest to the serial string, changing shorts to bytes. + result /= 2; + for (i = 1; i < result; i++) + info.serial_number[i - 1] = buffer[i]; + info.serial_number[i - 1] = 0; + } + else + { + printf("errno(%d): %s\n", errno, strerror(errno)); + } + }*/ + + for(i = 0; i < cfg->bNumInterfaces;) + { + if( !BulkDevNonDrv_check( ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE ) ) + { + len -= *ptr; + ptr += *ptr; + continue; + } + + i++; + ifc = (struct usb_interface_descriptor *) ptr; + len -= ifc->bLength; + ptr += ifc->bLength; + + if( !BulkDevNonDrv_ChecHWIds(dev->idVendor, dev->idProduct, ifc->bInterfaceNumber) ) + continue; + + in = -1; + out = -1; + //info.ifc_class = ifc->bInterfaceClass; + //info.ifc_subclass = ifc->bInterfaceSubClass; + //info.ifc_protocol = ifc->bInterfaceProtocol; + + for(e = 0; e < ifc->bNumEndpoints; e++) + { + if(!BulkDevNonDrv_check(ptr, len, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE)) + return 0; + + ept = (struct usb_endpoint_descriptor *) ptr; + len -= ept->bLength; + ptr += ept->bLength; + + if((ept->bmAttributes & 0x03) != 0x02) + continue; + + if(ept->bEndpointAddress & 0x80) + { + in = ept->bEndpointAddress; + } + else + { + out = ept->bEndpointAddress; + } + } + + //info.has_bulk_in = (in != -1); + //info.has_bulk_out = (out != -1); + *ept_in_id = in; + *ept_out_id = out; + *ifc_id = ifc->bInterfaceNumber; + //printf("ept_in_id: %d, ept_out_id: %d, ifc_id: %d\n", *ept_in_id, *ept_out_id, *ifc_id); + + return 1; + } + return 0; +} +int BulkDevNonDrv_Write(USB_HANDLE *h, const void *_data, int len) +{ + unsigned char *data = (unsigned char*) _data; + unsigned count = 0; + struct usbdevfs_bulktransfer bulk; + int n; + + if(h->nPipeOut == 0) + { + return -1; + } + + if(len == 0) + { + bulk.ep = h->nPipeOut; + bulk.len = 0; + bulk.data = data; + bulk.timeout = 0; + + n = ioctl(h->hDevHandle, USBDEVFS_BULK, &bulk); + if(n != 0) + { +#if DEBUG_MODE + printf("1ERROR: n = %d, errno = %d (%s)\n", + n, errno, strerror(errno)); +#endif + + return -1; + } + return n; + } + + while(len > 0) + { + int xfer; + xfer = len; + bulk.ep = h->nPipeOut; + bulk.len = xfer; + bulk.data = data; + bulk.timeout = 5000; + n = ioctl(h->hDevHandle, USBDEVFS_BULK, &bulk); + if(n != xfer) + { +#if DEBUG_MODE + printf("2ERROR: n = %d, errno = %d (%s)\n", + n, errno, strerror(errno)); +#endif + return -1; + } + + count += xfer; + len -= xfer; + data += xfer; + } + return count; +} + +int BulkDevNonDrv_Read(USB_HANDLE *h, void *_data, int len, int timeout) +{ + unsigned char *data = (unsigned char*) _data; + unsigned count = 0; + struct usbdevfs_bulktransfer bulk; + int n, retry; + + if(h->nPipeIn == 0) + { + return -1; + } + + while(len > 0) + { + int xfer = len; + //int xfer = (len > 4096) ? 4096 : len; + bulk.ep = h->nPipeIn; + bulk.len = xfer; + bulk.data = data; + bulk.timeout = timeout; + retry = 0; + + do + { + n = ioctl(h->hDevHandle, USBDEVFS_BULK, &bulk); + if( n < 0 ) + { + + if ( ++retry > MAX_RETRIES ) + { +#if DEBUG_MODE + printf("ERROR: n = %d, errno = %d (%s)\n",n, errno, strerror(errno)); +#endif + + return -1; + } + usleep(10000); + } + } + while( n < 0 ); + + count += n; + len -= n; + data += n; + + if(n < xfer) + { + break; + } + } + + return count; +} diff --git a/fbfdownloader/src/BulkDevNonDrv_Linux.h b/fbfdownloader/src/BulkDevNonDrv_Linux.h new file mode 100644 index 00000000..bd563655 --- /dev/null +++ b/fbfdownloader/src/BulkDevNonDrv_Linux.h @@ -0,0 +1,156 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) +#include +#else +#include +#endif +#include + +#ifdef __ANDROID__ +#include +#endif + +#define MAX_DEVNUM 5 +#define MAX_FILE_LENGTH 1024 + +static int HWIds_WTPTPTable[37][3] = +{ + {0x8086, 0xE001, -1}, + {0x8086, 0xC001, -1}, + {0x8086, 0xD001, -1}, + {0x1286, 0x8100, -1}, + {0x1286, 0x8101, -1}, + {0x1286, 0x8102, -1}, + {0x1286, 0x8103, -1}, + {0x1286, 0x8104, -1}, + {0x1286, 0x8105, -1}, + {0x1286, 0x8106, -1}, + {0x1286, 0x8111, -1}, + {0x1286, 0x8112, -1}, + {0x1286, 0x8113, -1}, + {0x1286, 0x8114, -1}, + {0x1286, 0x8115, -1}, + {0x1286, 0x8116, -1}, + {0x1286, 0x8117, -1}, + {0x1286, 0x8118, -1}, + {0x1286, 0x8128, -1}, + {0x1286, 0x8129, -1}, + {0x1286, 0x812a, -1}, + {0x1286, 0x8130, -1}, + {0x1286, 0x8164, -1}, + {0x1286, 0x8170, -1}, + {0x1286, 0x8165, -1}, + {0x1286, 0x8174, -1}, + {0x1286, 0x8175, -1}, + {0x1286, 0x8181, -1}, + {0x1286, 0x8182, -1}, + {0x1286, 0x8189, -1}, + {0x1286, 0x8167, -1}, + {0x2ECC, 0x3001, -1}, + {0x2ECC, 0x3002, -1}, + {0x2ECC, 0x3003, -1}, + {0x19D2, 0x1491, -1}, + {0x305A, 0x1413, -1}, + + {0x0, 0x0, 0x0} +}; + +static int HWIds_USBDiagTable[11][3] = +{ + {0x1286, 0x4E3C, 0}, + {0x1286, 0x4E38, 4}, + {0x1286, 0x4E2C, 0}, + {0x1286, 0x4E28, 4}, + {0x1286, 0x4E30, 0}, + {0x1286, 0x4E31, 2}, + {0x0BB4, 0x4E49, 0}, + {0x0BB4, 0x4E4A, 4}, + {0x0BB4, 0x4E4D, 3}, + {0x0BB4, 0x4E4E, 0}, + {0x0, 0x0, 0x0} +}; + + +static int (*HWIds_CurrentTable)[3] = HWIds_WTPTPTable; + +typedef struct _USB_HANDLE +{ + char DevName[256]; + char iSerialNumber[256]; + int hDevHandle; + int nPipeIn; + int nPipeOut; + + +} USB_HANDLE, *PUSB_HANDLE; +static void NEW_USB_HANDLE(PUSB_HANDLE me) +{ + memset(me->DevName, 0, sizeof(me->DevName)); + memset(me->iSerialNumber, 0, sizeof(me->iSerialNumber)); + me->hDevHandle = -1; + me->nPipeIn = -1; + me->nPipeOut = -1; +} + +static void COPY_USB_HANDLE(PUSB_HANDLE me, PUSB_HANDLE pusb) +{ + strcpy(me->DevName, pusb->DevName); + strcpy(me->iSerialNumber, pusb->iSerialNumber); + me->hDevHandle = pusb->hDevHandle; + me->nPipeIn = pusb->nPipeIn; + me->nPipeOut = pusb->nPipeOut; +} + + +typedef struct _USB_IFC_INFO +{ + unsigned short dev_vendor; + unsigned short dev_product; + + unsigned char dev_class; + unsigned char dev_subclass; + unsigned char dev_protocol; + + unsigned char ifc_class; + unsigned char ifc_subclass; + unsigned char ifc_protocol; + + unsigned char has_bulk_in; + unsigned char has_bulk_out; + + unsigned char writable; + + char serial_number[256]; +} USB_IFC_INFO, *PUSB_IFC_INFO; + +int BulkDevNonDrv_OpenDev(USB_HANDLE *usb); +int BulkDevNonDrv_CloseDev(USB_HANDLE *usb); +int BulkDevNonDrv_Write(USB_HANDLE *h, const void *_data, int nLen); +int BulkDevNonDrv_Read(USB_HANDLE *h, void *_data, int nLen, int timeout); +int BulkDevNonDrv_CheckDevForNetLink(USB_HANDLE *usb, const char *NetLinkBuff, int nBuffLen, int *bAdd); +int BulkDevNonDrv_WaitDev(); +int BulkDevNonDrv_FindAllSupportedDevices(PUSB_HANDLE hUSBArray[]); +int BulkDevNonDrv_check(void *_desc, int nLen, unsigned int type, int size); +int BulkDevNonDrv_badname(const char *name); +int BulkDevNonDrv_ChecHWIds(long idVendor, long idProduct, long MI); +int BulkDevNonDrv_IsSupported(const char *NetLinkBuff, int nBuffLen, char *Dev_Name, int *nDevNameLen, int *bAdd); +int BulkDevNonDrv_GetPipeOfDev(/*int fd, */char *ptr, int nLen, int *ept_in_id, int *ept_out_id, int *ifc_id); +#define BulkDevNonDrv_ChecHWIds2(a,b) BulkDevNonDrv_ChecHWIds(a,b,-1) \ No newline at end of file diff --git a/fbfdownloader/src/CommonFun.c b/fbfdownloader/src/CommonFun.c new file mode 100644 index 00000000..020860d1 --- /dev/null +++ b/fbfdownloader/src/CommonFun.c @@ -0,0 +1,190 @@ +#include "kstring.h" +#include "CommonFun.h" +#include +#ifdef _WINDOWS +#include +#endif +#define MAX_FILE_LENGTH 1024 +#pragma warning ( disable : 4996) +#ifdef MACDOWNLOAD +#include +#endif + +kstring_t GetAppPath() +{ + kstring_t strRet = { 0, 0, NULL }; + TCHAR exeFullPath[MAX_FILE_LENGTH] = {0}; + TCHAR exeAbsFullPath[MAX_FILE_LENGTH] = {0}; +#ifdef LINUX +#ifdef MACDOWNLOAD + UINT32 size = MAX_FILE_LENGTH; + _NSGetExecutablePath(exeFullPath, &size); + //exeFullPath[size] = '\0'; + realpath(exeFullPath,exeAbsFullPath); + TCHAR *p = _tcsrchr(exeAbsFullPath,'/'); + if(p) *p = 0; +#if PRINTLOG + tprintf(_T("GetAppPath: %s.....\n\n"),exeAbsFullPath); +#endif + kputs(exeAbsFullPath,&strRet); + return strRet; +#else + + readlink ("/proc/self/exe", exeFullPath, MAX_FILE_LENGTH); + TCHAR *p = _tcsrchr(exeFullPath,'/'); + if(p) *p = 0; + kputs(exeFullPath,&strRet); + return strRet; +#endif + +#else + kstring_t strAppPath = {0,0,NULL}; + TCHAR szFullExeName[MAX_FILE_LENGTH]; + DWORD nResult = ::GetModuleFileName(NULL, szFullExeName, MAX_FILE_LENGTH); + kstring_t strFullFileName= {0,0,NULL}; + kputs(szFullExeName,&strFullFileName); + char* cPos = strrchr(szFullExeName,'\\'); + *cPos = 0; + kputs(szFullExeName,&strAppPath); + return strAppPath; +#endif + +} + + + + +void DelFile(const TCHAR* pszFile) +{ + if (ACCESS_FILE_EXIST != taccess(pszFile,ACCESS_FILE_EXIST)) + { + return; + } +#ifdef LINUX + chmod(pszFile,0777); + TCHAR szBuffer[MAX_FILE_LENGTH]; + memset(szBuffer,0,sizeof(TCHAR)*MAX_FILE_LENGTH); + tsnprintf(szBuffer,sizeof(szBuffer),_T("rm -f %s"),pszFile); + system(szBuffer); +#else + SetFileAttributes(pszFile,FILE_ATTRIBUTE_NORMAL); + DeleteFile(pszFile); +#endif +} + + + +BOOL IsFileExist(const TCHAR *pFileName) +{ + if(taccess(pFileName,0)!=0) + { + return FALSE; + } + return TRUE; +} + + + +unsigned int Str2Uint32 (const TCHAR* pValue) +{ + unsigned int iRetVal = 0; + if (pValue[0]== _T('0') && (pValue[1]== _T('x') || pValue[1]== _T('X'))) + tsscanf( pValue, _T("%x"), &iRetVal ); + else + tsscanf( pValue, _T("%i"), &iRetVal ); + return iRetVal; +} + + +UINT64 TranslateEx (kstring_t sValue) +{ + int *fields,n; + if(strstr(sValue.s,_T("0xffffffffff"))!=NULL|| + strstr(sValue.s,_T("0xFFFFFFFFFF"))!=NULL) + { + UINT64 iRetVal = 0xFFFFFFFFFFll; + return iRetVal; + } + if(strstr(sValue.s,_T("0xffffffff"))!=NULL|| + strstr(sValue.s,_T("0xFFFFFFFF"))!=NULL) + { + return 0xFFFFFFFF; + } + + + UINT64 iRetVal = 0; + // remove leading whitespace + // remove any trailing whitespace + fields = ksplit(&sValue, 0, &n); + kstrcpy(&sValue,sValue.s+fields[0]); + free(fields); + + if(strstr(sValue.s,_T("0x"))!=NULL || strstr(sValue.s,_T("0X"))!=NULL) + { + tsscanf( sValue.s, _T("%llx"), &iRetVal ); + } + else + { + tsscanf( sValue.s, _T("%lli"), &iRetVal ); + } + + return iRetVal; +} + + +void EndianConvertMasterBlockHeader(MasterBlockHeader *mbHeader) +{ + int i; + for (i = 0; i < NUM_OF_SUPPORTED_FLASH_DEVS; i++){ + mbHeader->Flash_Device_Spare_Area_Size[i] = le16toh(mbHeader->Flash_Device_Spare_Area_Size[i]); + } + mbHeader->Format_Version = le16toh(mbHeader->Format_Version); + mbHeader->Size_of_Block = le16toh(mbHeader->Size_of_Block); + mbHeader->Bytes_To_Program = le32toh(mbHeader->Bytes_To_Program); + mbHeader->Bytes_To_Verify = le32toh(mbHeader->Bytes_To_Verify); + mbHeader->Number_of_Bytes_To_Erase = le32toh(mbHeader->Number_of_Bytes_To_Erase); + mbHeader->Main_Commands = le32toh(mbHeader->Main_Commands); + mbHeader->nOfDevices = le32toh(mbHeader->nOfDevices); + mbHeader->DLerVersion = le32toh(mbHeader->DLerVersion); + for (i = 0; i < MAX_NUMBER_OF_FLASH_DEVICES_IN_MASTER_HEADER; i++){ + mbHeader->deviceHeaderOffset[i] = le32toh(mbHeader->deviceHeaderOffset[i]); + } +} + +void EndianConvertDeviceHeader_V11(DeviceHeader_V11 *pDeviceHeader) +{ + int i; + pDeviceHeader->DeviceFlags = le32toh(pDeviceHeader->DeviceFlags); + for (i = 0; i < 16; i++){ + pDeviceHeader->DeviceParameters[i] = le32toh(pDeviceHeader->DeviceParameters[i]); + } + pDeviceHeader->FlashOpt.EraseAll = le32toh(pDeviceHeader->FlashOpt.EraseAll); + pDeviceHeader->FlashOpt.ResetBBT = le32toh(pDeviceHeader->FlashOpt.ResetBBT); + pDeviceHeader->FlashOpt.NandID = le32toh(pDeviceHeader->FlashOpt.NandID); + for (i = 0; i < MAX_RESEVERD_LEN-1; i++){ + pDeviceHeader->FlashOpt.Reserved[i] = le32toh(pDeviceHeader->FlashOpt.Reserved[i]); + } + pDeviceHeader->FlashOpt.Skip_Blocks_Struct.Total_Number_Of_SkipBlocks = le32toh(pDeviceHeader->FlashOpt.Skip_Blocks_Struct.Total_Number_Of_SkipBlocks); + for (i = 0; i < MAX_NUM_SKIP_BLOCKS; i++){ + pDeviceHeader->FlashOpt.Skip_Blocks_Struct.Skip_Blocks[i] = le32toh(pDeviceHeader->FlashOpt.Skip_Blocks_Struct.Skip_Blocks[i]); + } + pDeviceHeader->ProductionMode = le32toh(pDeviceHeader->ProductionMode); + for (i = 0; i < MAX_RESEVERD_LEN-2; i++){ + pDeviceHeader->Reserved[i] = le32toh(pDeviceHeader->Reserved[i]); + } + pDeviceHeader->nOfImages = le32toh(pDeviceHeader->nOfImages); + for (i = 0; i < MAX_NUMBER_OF_IMAGE_STRUCTS_IN_DEVICE_HEADER; i++){ + pDeviceHeader->imageStruct[i].Image_ID = le32toh(pDeviceHeader->imageStruct[i].Image_ID); + pDeviceHeader->imageStruct[i].Image_In_TIM = le32toh(pDeviceHeader->imageStruct[i].Image_In_TIM); + pDeviceHeader->imageStruct[i].Flash_partition = le32toh(pDeviceHeader->imageStruct[i].Flash_partition); + pDeviceHeader->imageStruct[i].Flash_erase_size = le32toh(pDeviceHeader->imageStruct[i].Flash_erase_size); + pDeviceHeader->imageStruct[i].commands = le32toh(pDeviceHeader->imageStruct[i].commands); + pDeviceHeader->imageStruct[i].First_Sector = le32toh(pDeviceHeader->imageStruct[i].First_Sector); + pDeviceHeader->imageStruct[i].length = le32toh(pDeviceHeader->imageStruct[i].length); + pDeviceHeader->imageStruct[i].Flash_Start_Address = le32toh(pDeviceHeader->imageStruct[i].Flash_Start_Address); + for (int j = 0; j < MAX_RESEVERD_LEN; j++){ + pDeviceHeader->imageStruct[i].Reserved[j] = le32toh(pDeviceHeader->imageStruct[i].Reserved[j]); + } + pDeviceHeader->imageStruct[i].ChecksumFormatVersion2 = le32toh(pDeviceHeader->imageStruct[i].ChecksumFormatVersion2); + } +} diff --git a/fbfdownloader/src/CommonFun.h b/fbfdownloader/src/CommonFun.h new file mode 100644 index 00000000..ab456197 --- /dev/null +++ b/fbfdownloader/src/CommonFun.h @@ -0,0 +1,41 @@ +#pragma once + +#include "Typedef.h" +#include +#if !defined(LINUX) +#include "StdAfx.h" +#include +#include +#include +#include +#include "Shlwapi.h" +#else +#include +#include +#include +#endif +#include "downloader.h" +#define _countof(array) (sizeof(array) / sizeof(array[0])) + +kstring_t GetAppPath(); +void DelFile(const TCHAR* pszFile); + +unsigned int Str2Uint32 (const TCHAR* pValue); +UINT64 TranslateEx (kstring_t sValue); +BOOL IsFileExist(const TCHAR *pFileName); + +//inline function +inline int CloseFilePtr(FILE** fpFile) +{ + int ret = 0; + if (NULL != *fpFile) + { + ret = fclose(*fpFile); + *fpFile = NULL; + } + return ret; +} + +void EndianConvertMasterBlockHeader(MasterBlockHeader *mbHeader); + +void EndianConvertDeviceHeader_V11(DeviceHeader_V11 *pDeviceHeader); \ No newline at end of file diff --git a/fbfdownloader/src/ConvetEdian.c b/fbfdownloader/src/ConvetEdian.c new file mode 100644 index 00000000..a2342213 --- /dev/null +++ b/fbfdownloader/src/ConvetEdian.c @@ -0,0 +1,60 @@ + +#include "ConvetEdian.h" + + + + +UINT32 Endian32ConvertLToB(struct CConvertLT2B *me,UINT32 InputNum) +{ + if(!me->m_bIsLittleEndian) ////big endian ,please convert + { + UINT32 ConvertNum =((((UINT32)(InputNum) & 0xff000000) >> 24) + + (((UINT32)(InputNum) & 0x00ff0000) >> 8) + + (((UINT32)(InputNum) & 0x0000ff00) << 8) + + (((UINT32)(InputNum) & 0x000000ff) << 24)); + return ConvertNum; + + } + else + { + return InputNum; + } + +} + + +UINT16 Endian16ConvertLToB(struct CConvertLT2B *me,UINT16 InputNum) +{ + if(!me->m_bIsLittleEndian) //big endian ,please convert + { + return ((((UINT16)(InputNum) & 0xff00) >> 8) |(((UINT16)(InputNum) & 0x00ff) << 8)); + } + else + { + return InputNum; + } + +} + +void IsLittleEndian(struct CConvertLT2B *me) +{ + int a=1; + char *b; + b = (char *)&a; + if((*b)==1) + { + me->m_bIsLittleEndian = TRUE; + //tprintf (_T("Little Endian\n")); + } + else + { + me->m_bIsLittleEndian = FALSE; + //tprintf (_T("Big Endian\n")); + } +} +void NewCConvertLT2B (struct CConvertLT2B *me) +{ + me->m_bIsLittleEndian = TRUE; + IsLittleEndian(me); +} + diff --git a/fbfdownloader/src/ConvetEdian.h b/fbfdownloader/src/ConvetEdian.h new file mode 100644 index 00000000..b5dc6a9f --- /dev/null +++ b/fbfdownloader/src/ConvetEdian.h @@ -0,0 +1,16 @@ +#pragma once + +#include "Typedef.h" +#include +#include +struct CConvertLT2B +{ + BOOL m_bIsLittleEndian; +}; + +UINT32 Endian32ConvertLToB(struct CConvertLT2B *me,UINT32 InputNum); +UINT16 Endian16ConvertLToB(struct CConvertLT2B *me,UINT16 InputNum); +void IsLittleEndian(struct CConvertLT2B *me); +void NewCConvertLT2B (struct CConvertLT2B *me); + + diff --git a/fbfdownloader/src/EnumVal.h b/fbfdownloader/src/EnumVal.h new file mode 100644 index 00000000..fbe9b4c2 --- /dev/null +++ b/fbfdownloader/src/EnumVal.h @@ -0,0 +1,145 @@ +#pragma once +enum eProcessorType { PXA_NONE = -1, + PXA168 = 0, + PXA30x, PXA31x, PXA32x, + PXA688, + PXA91x, PXA92x, PXA93x, PXA94x, PXA95x, + ARMADA168, + PXA2128, + MG1, + TAVOR_PV_MG2, + ESHEL, + PXA988, + PXA1088, + PXA1202, + PXA1802, + PXA1928, + PXA1920, + PXA1822, + ARMADA620, + ESHEL_LTE, + ARMADA622, + WUKONG, + PXA1826, + PXA1908, + PXA1936, + PXA1956, + PXA1918, + PXAMAX_PT +}; + + + + +typedef enum +{ + BLF_V_3_0_0 = 0, + BLF_V_2_0_0 = 1, + UNKNOWN_VERSION = 0xFF + +}eBLFVersion; + +typedef enum +{ + FLASH = 0, + DDR, + UNKNOWN_TYPE +}EUploadType; +typedef enum _eFlashType +{ + FLASH_NAND = 0, + FLASH_EMMC = 1, + FLASH_SPINOR = 2, + FLASH_ONENAND = 3, + FLASH_SPINAND = 4, + FLASH_UNKNOWN = 10 +} +eFlashType; + +enum eEraseAllMode +{ + ERASE_ALL_NOTSET = 0, + ERASE_ALL_BEFOREBURNING = 1, + ERASE_ALL_WIHTOUTBURNING = 2, + UNKNOWN_MODE = 0xFF + +}; + +typedef enum _eUserBootMode +{ + UE_NORESET = 0, + UE_RESET = 1, + UNKNOWN_BOOT_MODE = 0xFF + +} +eUserBootMode; +typedef enum +{ + PLAT_PXA92x_Old=0, + PLAT_PXA92x , + PLAT_MMP2 , + PLAT_WUKONG, + PLAT_NEVO,// + PLAT_MMP3, + PLAT_NEZHA, + PLAT_NEVO_OTA, + PLAT_EMEI, + PLAT_HELAN, + PLAT_EDEN, //PLAT_EDEN_Zx + PLAT_HELANLTE, + PLAT_NEZHA2, + PLAT_HELAN2, + PLAT_EDEN_A0, + PLAT_NEZHA3, + PLAT_ULC1, + PLAT_HELAN3, + PLAT_HELAN4, + PLAT_ULC2, + PLAT_UNKNOWN = 0xff +} ePlatForm; + +//subtype enum for upload +enum EUploadSubType +{ + DEFAULT_FLASH_PROBE = 0, + HSI1, + X16_ONENAND, + XIP_FLASH_X16, + X16_NAND_HAMMING, + X16_XIP_SIBLEY, + NAND_X8_HAMMING, + SDMMC_FLASH_OPT0, + SDMMC_FLASH_OPT1, + SDMMC_FLASH_OPT2, + SPI_FALSH, + SDMMC_FLASH_OPT3, + SDMMC_FLASH_OPT4, + X16_NAND_BCH, + X8_NAND_BCH, + CS1_XIP_FLASH, // XIP (CS1) - for SV only + NAND_FLASH_X16_BCH_OPT1, // x16 NAND BCH (16 bit correction per 1K) + NAND_FLASH_X8_BCH_OPT1, // x8 NAND BCH (16 bit correction per 1K) + NAND_FLASH_X16_NO_ECC,// x16 NAND No ECC (ECC is done by flash device) + NAND_FLASH_X8_NO_ECC, // x8 NAND No ECC (ECC is done by flash device) + SDIO_BUS, + BOOTSPI_FLASH, + SPI_NAND_FLASH = 26, + UNKOWN_SUBTYPE = 0xff +}; + +enum eProductMode{ + DO_NOTHING_FUSE, + ONLY_BURN_FUSE, + ONLY_READ_FUSE, + BURN_READ_FUSE, + DONTBURN_ONLY_BURN_FUSE, + DONTBURN_ONLY_READ_FUSE, + DONTBURN_BURN_READ_FUSE, +}; + +enum eDDREMMCTypeMode{ + NoneType, + DDRType, + EMMCType, + DDRandEMMCType, +}; diff --git a/fbfdownloader/src/ErrorCode.h b/fbfdownloader/src/ErrorCode.h new file mode 100644 index 00000000..74df362a --- /dev/null +++ b/fbfdownloader/src/ErrorCode.h @@ -0,0 +1,369 @@ +/************************************************************************** +** +** (C) Copyright December 2006 Marvell International Ltd. +** +** All Rights Reserved. +** +** +** THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE +** IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR +** PURPOSE ARE EXPRESSLY DISCLAIMED. +** +** FILENAME: ErrorCodes.h +** +** PURPOSE: Contains DKB error definitions +** +******************************************************************************/ + +#pragma once + +#ifndef ERROR_CODE_H +#define ERROR_CODE_H +#include "Macrodef.h" +#define MAXERRORCODES 1024 +#define MAXNOTIFICATIONSCODES 256 + +typedef enum EDDREMMCMatchResult +{ + kMatchNoError, + kDDRMismatchError, + kEMMCMismatchError, + kImagePreparationError, +} eDDREMMCMatchResult; + +#ifndef COMPRESSDATA +typedef struct +{ + unsigned int ErrorCode; + TCHAR Description[100]; +} ERRORCODETABLE; + +typedef struct +{ + unsigned int NotificationCode; + TCHAR Description[100]; +} NOTIFICATIONTABLE; +#else + typedef struct + { + unsigned int ErrorCode; + } ERRORCODETABLE; + + typedef struct + { + unsigned int NotificationCode; + } NOTIFICATIONTABLE; + +#endif + /* General error code definitions 0x0 - 0x1F + **/ + +#define PlatformBusy 0x1 +#define PlatformReady 0x2 +#define PlatformResetBBT 0x3 +#define PlatformEraseAllFlash 0x4 + + +#define PlatformDisconnect 0x5 +#define PlatformEraseAllFlashDone 0x6 +#define PlatformEraseAllFlashWithoutBurn 0x7 +#define PlatformEraseAllFlashWithoutBurnDone 0x8 +#define PlatformFuseOperationStart 0x9 +#define PlatformFuseOperationDone 0xA +#define PlatformUEInfoStart 0xB +#define PlatformUEInfoDone 0xc + + +#define PXA92x_PlatformBusy 0x7 +#define PXA92x_PlatformReady 0x8 + +#define PXA92x_PlatformDisconnect 0xC +#define ERRORFLAG 0x64 + + +#define NoError 0x0 +#define NotFoundError 0x1 +#define GeneralError 0x2 +#define WriteError 0x3 +#define ReadError 0x4 +#define NotSupportedError 0x5 +#define InvalidPlatformConfigError 0x6 +#define InvalidPlatformState 0x7 +#define InvalidSizeError 0x9 +#define ProbeListExhaustError 0xA +#define DDR_NotInitializedError 0xB +#define UnknownReservedPackage 0xD +#define NULLPointer 0xE +#define NANDIDDISMATCH 0xF +#define FBF_VersionNotMatch 0x10 +#define FBF_DeviceMoreThanOne 0x11 +#define PlatformConfigBuckError 0x12 +#define ChipIdMismatch 0x13 + + + +// Flash Related Errors 0x20 - 0x3F +#define EraseError 0x20 +#define ProgramError 0x21 +#define InvalidBootTypeError 0x22 +#define ProtectionRegProgramError 0x23 +#define NoOTPFound 0x24 +#define BBTReadError 0x25 +#define MDOCInitFailed 0x26 +#define OneNandInitFailed 0x27 +#define MDOCFormatFailed 0x28 +#define BBTExhaustedError 0x29 +#define NANDNotFound 0x2A +#define SDMMCNotFound 0x2B +#define FlexOneNANDNotFound 0x2C +#define SDMMCReadError 0x2D +#define XIPReadError 0x2E +#define FlexOneNANDError 0x2F +#define FlashDriverInitError 0x30 +#define FlashFuncNotDefined 0x31 +#define OTPError 0x32 +#define InvalidAddressRangeError 0x33 +#define FlashLockError 0x34 +#define ReadDisturbError 0x35 +#define FlashReadError 0x36 +#define SPIFlashNotResponding 0x37 +#define ImageOverlayError 0x38 +#define FlashAddrNotChunkAlign 0x39 +#define FlashAddrNotWordAlign 0x3A +#define BBTOUTOFRANGE 0x3B +#define FlashWriteVerifyError 0x3C +#define FlashAddrOutOfRange 0x3d + +// DFC Related Errors 0x40 - 0x4F +#define DFCDoubleBitError 0x40 +#define DFCSingleBitError 0x41 +#define DFCCS0BadBlockDetected 0x42 +#define DFCCS1BadBlockDetected 0x43 +#define DFCInitFailed 0x44 +#define DFCONFIConfigError 0x45 +#define DFC_WRREQ_TO 0x46 +#define DFC_WRCMD_TO 0x47 +#define DFC_RDDREQ_TO 0x48 +#define DFC_RDY_TO 0x49 +#define DFCCS0CommandDoneError 0x4A +#define DFCCS1CommandDoneError 0x4B +#define DFC_PGDN_TO 0x4C +// SPI Related Errors +#define SPINORPROGRAMFAIL 0x50 +#define SPINORERASEFAIL 0x51 + +// Security Related Errors 0x60 - 0x8F +#define InvalidOEMVerifyKeyError 0x60 +#define InvalidOBMImageError 0x61 +#define SecureBootFailureError 0x62 +#define InvalidSecureBootMethodError 0x63 +#define UnsupportedFlashError 0x64 +#define InvalidCaddoFIFOEntryError 0x65 +#define InvalidCaddoKeyNumberError 0x66 +#define InvalidCaddoKeyTypeError 0x67 +#define RSADigitalSignatureDecryptError 0x68 +#define InvalidHashValueLengthError 0x69 +#define InvalidTIMImageError 0x6A +#define HashSizeMismatch 0x6B +#define InvalidKeyHashError 0x6C +#define TIMNotFound 0x6D +#define WTMStateError 0x6E +#define FuseRWError 0x6F +#define InvalidOTPHashError 0x70 +#define CRCFailedError 0x71 +#define SaveStateNotFound 0x72 +#define WTMInitializationError 0x73 +#define ImageNotFound 0x74 +#define InvalidImageHash 0x75 +#define MicroCodePatchingError 0x76 +#define SetJtagKeyError 0x77 +#define WTMDisabled 0x78 +#define PlatformVerifyFailure 0x79 +#define ImageLoadError 0x7A +#define IPPCPHASHERROR 0x7B + +// Download Protocols 0x90 - 0x9F +#define DownloadPortError 0x90 +#define DownloadError 0x91 +#define FlashNotErasedError 0x92 +#define InvalidKeyLengthError 0x93 +#define DownloadImageTooBigError 0x94 +#define UsbPreambleError 0x95 +#define TimeOutError 0x96 +#define UartReadWriteTimeOutError 0x97 +#define UnknownImageError 0x98 +#define MessageBufferFullError 0x99 +#define NoEnumerationResponseTimeOutError 0x9A +#define UnknownProtocolCmd 0x9B +#define UsbRxError 0x9C +#define ForceDownloadPseudoError 0x9D +#define UsbTxError 0x9E + +//JTAG ReEnable Error Codes 0xB0 - 0xCF +#define JtagReEnableError 0xB0 +#define JtagReEnableOEMPubKeyError 0xB1 +#define JtagReEnableOEMSignedPassWdError 0xB2 +#define JtagReEnableTimeOutError 0xB3 +#define JtagReEnableOEMKeyLengthError 0xB4 + +// SDMMC Errors 0xD0-0xE5 +#define SDMMC_SWITCH_ERROR 0xD0 +#define SDMMC_ERASE_RESET_ERROR 0xD1 +#define SDMMC_CIDCSD_OVERWRITE_ERROR 0xD2 +#define SDMMC_OVERRUN_ERROR 0xD3 +#define SDMMC_UNDERUN_ERROR 0xD4 +#define SDMMC_GENERAL_ERROR 0xD5 +#define SDMMC_CC_ERROR 0xD6 +#define SDMMC_ECC_ERROR 0xD7 +#define SDMMC_ILL_CMD_ERROR 0xD8 +#define SDMMC_COM_CRC_ERROR 0xD9 +#define SDMMC_LOCK_ULOCK_ERRROR 0xDA +#define SDMMC_LOCK_ERROR 0xDB +#define SDMMC_WP_ERROR 0xDC +#define SDMMC_ERASE_PARAM_ERROR 0xDD +#define SDMMC_ERASE_SEQ_ERROR 0xDE +#define SDMMC_BLK_LEN_ERROR 0xDF +#define SDMMC_ADDR_MISALIGN_ERROR 0xE0 +#define SDMMC_ADDR_RANGE_ERROR 0xE1 +#define SDMMCDeviceNotReadyError 0xE2 +#define SDMMCInitializationError 0xE3 +#define SDMMCDeviceVoltageNotSupported 0xE4 +#define SDMMCWriteError 0xE5 +#define SDMMCAltBootDataAlignmentError 0xE6 +#define SDMMC_SGPT_ILLEGAL_LENGTH 0xE7 + +// SDIO Errors 0xF0 - +#define SDIOReadError 0xF0 +#define SDIOWriteError 0xF1 +#define SDIOOutOfSyncError 0xF2 +#define SDIONullBuffer 0xF3 +#define SDIOBufferMisalignError 0xF4 +#define SDIOImageSizeError 0xF5 + + +// WTM FuseBlock Errors +#define FUSE_FuseBlockNotActive 0x100 +#define FUSE_BufferTooSmall 0x101 +#define FUSE_FuseBlockLocked 0x102 +#define FUSE_UnsupportedFuseBlock 0x103 +#define FUSE_IncompleteBurnRequest 0x104 +#define FUSE_NoBurnRequest 0x105 +#define FUSE_FuseBlockFieldNotActive 0x106 +#define FUSE_BurnError 0x107 +#define FUSE_FuseBlockFieldOverflow 0x108 +#define FUSE_InvalidFuseBlockField 0x109 +#define FUSE_FuseBlockCompareFailed 0x10A +#define FUSE_InvalidState 0x10B +#define FUSE_InvalidBufferSize 0x10C +#define FUSE_BitSetError 0x10D +#define FUSE_FuseBlockLockedAndNotReadable 0x10E +#define FUSE_FuseBlockFieldFull 0x10F +#define FUSE_FuseSoftwareResetTimeout 0x110 +#define FUSE_FuseBurnTimeout 0x111 +#define FUSE_FuseBlockStickyBitSet 0x112 +#define FUSE_UsbPhyBandgapNotEnabled 0x113 +#define FUSE_UncorrectableEccError 0x114 +#define FUSE_FieldWriteProtectedByEcc 0x115 +#define FUSE_LastLogicalBitBurned 0x116 +#define FUSE_TamperError 0x117 +#define FUSE_FuseReprogrammingError 0x118 +#define FUSE_IncompleteFuseFieldsSetup 0x119 + +// GEU FuseBlock Errors +#define GEU_FuseBlockNotActive 0x100 +#define GEU_BufferTooSmall 0x101 +#define GEU_FuseBlockLocked 0x102 +#define GEU_UnsupportedFuseBlock 0x103 +#define GEU_IncompleteBurnRequest 0x104 +#define GEU_NoBurnRequest 0x105 +#define GEU_FuseBlockFieldNotActive 0x106 +#define GEU_BurnError 0x107 +#define GEU_FuseBlockFieldOverflow 0x108 +#define GEU_InvalidFuseBlockField 0x109 +#define GEU_FuseBlockCompareFailed 0x10A +#define GEU_InvalidState 0x10B +#define GEU_InvalidBufferSize 0x10C +#define GEU_BitSetError 0x10D +#define GEU_FuseBlockLockedAndNotReadable 0x10E +#define GEU_FuseBlockFieldFull 0x10F +#define GEU_FuseSoftwareResetTimeout 0x110 +#define GEU_FuseBurnTimeout 0x111 +#define GEU_FuseBlockStickyBitSet 0x112 +#define GEU_UsbPhyBandgapNotEnabled 0x113 +#define GEU_UncorrectableEccError 0x114 +#define GEU_FieldWriteProtectedByEcc 0x115 +#define GEU_LastLogicalBitBurned 0x116 +#define GEU_TamperError 0x117 +#define GEU_FuseReprogrammingError 0x118 +#define GEU_IncompleteFuseFieldsSetup 0x119 + + +// TrustZone Related Errors +#define TZ_Region0NotProtected 0x120 +#define TZ_FusesNotConfiguredForTrustzone 0x121 +#define TZ_PackageNotFound 0x122 +#define TZ_InitDisabled 0x123 +#define TZ_UnknownOperation 0x124 + +//DDR Related Error Codes +#define DDR_Package_Obsolete 0x200 +#define DDR_Unknown_Operation 0x201 +#define DDR_MemoryTest_Failed 0x202 +#define DDR_InitDisabled 0x203 +#define DDR_CMCC_Package_Obsolete 0x204 +#define DDR_Trustzone_Package_Obsolete 0x205 +#define DDR_PackageNotFound 0x206 +#define DDR_FusesNotConfiguredForTrustzone 0x207 + + + +//Instruction related codes +#define UnknownInstruction 0x300 +#define InstructionTimeout 0x301 +#define INSTR_InvalidAddress 0x302 +#define INSTR_InvalidScratchMemoryId 0x303 +#define INSTR_InvalidMaskOrValue 0x304 + +// sparse file related codes +#define Sparse_ImageLengthLimitExceeded 0x400 +#define Sparse_BadMagic 0x401 +#define Sparse_IncompatibleFormat 0x402 +#define Sparse_BadChunkSize 0x403 +#define Sparse_BogusDontCareChunk 0x404 +#define Sparse_UnknownChunkId 0x405 +#define Sparse_WriteError 0x406 + +//Relate to EMMC error +#define SDH_CMD_TIMEOUT_ERR 0x420 +#define SDH_CMD_CRC_ERR 0x421 +#define SDH_CMD_END_BIT_ERR 0x422 +#define SDH_CMD_INDEX_ERR 0x423 +#define SDH_DATA_TIMEOUT_ERR 0x424 +#define SDH_RD_DATA_CRC_ERR 0x425 +#define SDH_RD_DATA_END_BIT_ERR 0x426 +#define SDH_AUTO_CMD12_ERR 0x427 +#define SDH_ADMA_ERR 0x428 +#define SDH_TUNE_ERR 0x429 +#define SDH_SPI_ERR 0x42A +#define SDH_AXI_RESP_ERR 0x42B +#define SDH_CPL_TIMEOUT_ERR 0x42C +#define SDH_CRC_STATUS_ERR 0x42D + + +// DTIM related codes +#define IMAP_PackageNotFound 0x500 +#define IMAP_ErrorFormat 0x501 +#define IMAP_DTIMNotFound 0x502 +#define IMAP_DTIMLoadError 0x503 +#define IMAP_DTIMValidationFailed 0x504 +#define IMAP_BootFailed 0x505 +#define IMAP_KeyNotFound 0x506 +#define IMAP_ImageLoadError 0x507 +#define IMAP_ImageValidateError 0x508 + +// MRD related codes +#define MRD_BadMagic 0x520 +#define MRD_CheckSumNotMatch 0x521 +#define MRD_IMEINotMatch 0x522 + +#endif diff --git a/fbfdownloader/src/FBFDownloader.c b/fbfdownloader/src/FBFDownloader.c new file mode 100644 index 00000000..3d1c8f5d --- /dev/null +++ b/fbfdownloader/src/FBFDownloader.c @@ -0,0 +1,900 @@ +#include + +#include "CommonFun.h" +#include "downloader.h" +#include "WtptpDownLoad.h" +#include +#include "ParaDefine.h" +#include "BinFileWtp.h" +#include "kstring.h" +#include "fbfdownload.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SUCCEED 0 +#define FAILED 1 + +#define MIN_ARGS 3 + +#define FBF_TIMHEADER 'i' +#define FBF_FILE 'f' +#define DKB_TIMHEADER 't' +#define DKB_FILE 'd' +#define BIN_FILE 'b' +#define LOG_PATH 'p' +// #define PLATFORM_TYPE 'p' + +#define MAX_FILE_LENGTH 256 + + +kstring_t g_DkbTimPath={0,0,NULL}, g_DkbFilePath={0,0,NULL}, g_BinFilePath={0,0,NULL}; + +kstring_t strDeviceDetectFile={0,0,NULL}; +BOOL bDownload = TRUE; +BOOL bUpload = FALSE; +BOOL bSingle = TRUE; +BOOL btimeoutset = FALSE; +BOOL bIgnoreBlankLines = TRUE; +int exit_code = -1; +int timeout = 0; + +pthread_mutex_t mutex; +pthread_cond_t cond; + +int g_nDownloadPercent = 0; +int g_nBurnPercent = 0; + +const TCHAR* pszSWDReleaseDate = _T("2020-6-19"); +const TCHAR* pszSWDReleaseVersion = _T("4.9.0.7"); + +//char SWDLOCKFILE[255] = "/var/run/swdlinux.pid"; +char SWDLOCKFILE[255] = "./fbfdownloader.pid"; +extern char g_LogPath[255]; + +#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) + +#if DEBUG_MODE +BOOL bDebugTrace = TRUE; +#else +BOOL bDebugTrace = FALSE; +#endif + + +int lockfile(int fd) +{ + struct flock fl; + + fl.l_type = F_WRLCK; + fl.l_start = 0; + fl.l_whence = SEEK_SET; + fl.l_len = 0; + return(fcntl(fd, F_SETLK, &fl)); +} + +int already_running(void) +{ + int fd; + if (strlen(g_LogPath) > 0) + { + strncpy(SWDLOCKFILE,g_LogPath,_countof(SWDLOCKFILE)); + strncat(SWDLOCKFILE,"/fbfdownloader.pid",_countof(SWDLOCKFILE)); + } + fd = open(SWDLOCKFILE, O_RDWR | O_CREAT, LOCKMODE); + if (fd < 0) { + //syslog(LOG_ERR, "can't open %s: %s", SWDLOCKFILE, strerror(errno)); +#if PRINTLOG + printf("can't open %s: %s", SWDLOCKFILE, strerror(errno)); +#endif + exit(1); + } + if (lockfile(fd) < 0) { + if (errno == EACCES || errno == EAGAIN) { + close(fd); + return(1); + } + //syslog(LOG_ERR, "can't lock %s: %s", SWDLOCKFILE, strerror(errno)); +#if PRINTLOG + printf("can't lock %s: %s", SWDLOCKFILE, strerror(errno)); +#endif + exit(1); + } + //close(fd); + return(0); +} + +BOOL ParseCommandLine(int argc, char* argv[]) +{ + int currentOption = 1; + BYTE Option = 0; + + while (currentOption < argc) + { + + if (*argv[currentOption] == '-') + { + Option = *++argv[currentOption++]; + + switch (Option) + { + case FBF_FILE: + { +/* + TCHAR szFbfPath[MAX_FILE_LENGTH]; + memset(szFbfPath, 0, sizeof(TCHAR)*MAX_FILE_LENGTH); + _tcscpy(szFbfPath, argv[currentOption]); + tstring strFbfPath(szFbfPath); + + g_lpFbfImageList->push_back(strFbfPath); +*/ + } + break; + case FBF_TIMHEADER: + { + /* + TCHAR szFbfTimPath[MAX_FILE_LENGTH]; + memset(szFbfTimPath, 0, sizeof(TCHAR)*MAX_FILE_LENGTH); + _tcscpy(szFbfTimPath, argv[currentOption]); + tstring strFbfTimPath(szFbfTimPath); + + g_lpFbfImageList->push_front(strFbfTimPath); + */ + } + break; + case DKB_FILE: + { + // g_DkbFilePath = argv[currentOption]; + } + break; + case DKB_TIMHEADER: + { + // g_DkbTimPath = argv[currentOption]; + } + break; + case BIN_FILE: + { + kstrcpy(&g_BinFilePath, argv[currentOption]); + } + break; + case LOG_PATH: + { + strncpy(g_LogPath,argv[currentOption],_countof(g_LogPath)); + + if (strlen(g_LogPath) >0 && g_LogPath[strlen(g_LogPath)-1] == '/') + { + g_LogPath[strlen(g_LogPath)-1] = 0; + } + } + break; + default: + { +#if PRINTLOG + printf("\n Error: Command line option -%c is invalid!\n", Option); +#endif + return FALSE; + } + break; + } + } + else + { + currentOption++; + } + } + + return TRUE; +} + + +void CallbackProc(PProcInfo pNotifyInfo) +{ + //tprintf(_T("CallbackProc......\n")); + + if (!bIgnoreBlankLines) + { +#if PRINTLOG + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); +#endif + } + + + switch ((eProcessState)pNotifyInfo->eProcState) + { + case kProcConnecting: + { + g_nDownloadPercent = 0; +#if PRINTLOG + tprintf(_T("|%s:Add an device |\n"), pNotifyInfo->pszUSBPortAddress); +#endif + } + break; + case kProcDownloading: + { + if (!bIgnoreBlankLines) + { +#if PRINTLOG + tprintf(_T("|%s:Download percentage is:%d |\r"), pNotifyInfo->pszUSBPortAddress, pNotifyInfo->nDownloadedPercent); +#endif + } + else if (pNotifyInfo->nDownloadedPercent > g_nDownloadPercent) + { +#if PRINTLOG + tprintf(_T("|%s:Download percentage is:%d |\r"), pNotifyInfo->pszUSBPortAddress, pNotifyInfo->nDownloadedPercent); +#endif + g_nDownloadPercent = pNotifyInfo->nDownloadedPercent; + } + + if ( _tcscmp(pNotifyInfo->pszProcMsg, _T("BadBlkNum") ) == 0 ) + { + kstring_t g_strBBPath = GetAppPath(); + kstring_t strBBFile ={0,0,NULL}; + kputs(_T("/bbcs.txt"),&g_strBBPath); + FILE* BbcLogFile = _tfopen(g_strBBPath.s,_T("w")); + tfprintf (BbcLogFile,_T("%lf"),le32toh(pNotifyInfo->lpBadBlk.TotalBadBlocks)/le32toh(pNotifyInfo->lpBadBlk.TotalBlocks)); + fflush(BbcLogFile); + fclose(BbcLogFile); + free(g_strBBPath.s); + // tprintf(_T("\rFlash Info: TotalBadBlocks = %d, Total Blocks = %d"), + // le32toh(pNotifyInfo->lpBadBlk.TotalBadBlocks), le32toh(pNotifyInfo->lpBadBlk.TotalBlocks)); + + //To do your code, you can abort the download at certain bad blocks number. + /* if(((pNotifyInfo->lpBadBlk.TotalBadBlocks)*50) > pNotifyInfo->lpBadBlk.TotalBlocks) + { + tprintf(_T("|%s:Too many bad blocks |\n"), pNotifyInfo->pszUSBPortAddress); + exit_code = FAILED; + pthread_cond_signal(&cond); + } + */ + } + } + break; + case kProcAborting: + { +#if PRINTLOG + tprintf(_T("\n|%s:Abort in download |"), pNotifyInfo->pszUSBPortAddress); +#endif + exit_code = FAILED; + pthread_cond_signal(&cond); + + } + break; + case kProcCompleted: + { + if (bUpload) + { +#if PRINTLOG + tprintf(_T("|%s:Upload Successfully |\n"), pNotifyInfo->pszUSBPortAddress); +#endif + } + else + { +#if PRINTLOG + tprintf(_T("|%s:Burn Successfully |\n"), pNotifyInfo->pszUSBPortAddress); +#endif + } + + exit_code = SUCCEED; + pthread_cond_signal(&cond); + } + break; + case kProcBurningFlash: + { + if (!bIgnoreBlankLines) + { +#if PRINTLOG + tprintf(_T("|%s:Burning Flash percentage is:%d |\r"), pNotifyInfo->pszUSBPortAddress, pNotifyInfo->nDownloadedPercent); +#endif + } + else if (pNotifyInfo->nDownloadedPercent > g_nBurnPercent && pNotifyInfo->nDownloadedPercent <= 100) + { +#if PRINTLOG + tprintf(_T("|%s:Burning Flash percentage is:%d |\r"), pNotifyInfo->pszUSBPortAddress, pNotifyInfo->nDownloadedPercent); +#endif + g_nBurnPercent = pNotifyInfo->nDownloadedPercent; + } + + if ( _tcscmp(pNotifyInfo->pszProcMsg, _T("CRCS") ) == 0 ) + { +// tprintf(_T("\t\nBurning, Devices: MCPID: 0x%x, ImageNum: %d\n"), +// le32toh(pNotifyInfo->lpImageCrc.MCPID), le32toh(pNotifyInfo->lpImageCrc.ImageNum)); + kstring_t g_strAppPath = GetAppPath(); + kputs(_T("/crcs.txt"),&g_strAppPath); + FILE* CrcLogFile = _tfopen(g_strAppPath.s,_T("w")); + for(UINT32 i = 0; i < le32toh(pNotifyInfo->lpImageCrc.ImageNum); i++) + { +// tprintf(_T("ImageID: 0x%x, CrcData: 0x%8X\n"), +// le32toh(pNotifyInfo->lpImageCrc.ImageCRC[i].ImageID), le32toh(pNotifyInfo->lpImageCrc.ImageCRC[i].CRC32)); + if(i != le32toh(pNotifyInfo->lpImageCrc.ImageNum) -1) + tfprintf (CrcLogFile,_T("0x%08x-"),le32toh(pNotifyInfo->lpImageCrc.ImageCRC[i].CRC32)); + else + tfprintf (CrcLogFile,_T("0x%08x"),le32toh(pNotifyInfo->lpImageCrc.ImageCRC[i].CRC32)); + } + free(g_strAppPath.s); + fflush(CrcLogFile); + fclose(CrcLogFile); + } + + } + break; + case kProcUploadingData: + { +#if PRINTLOG + tprintf(_T("|%s:Uploading percentage is:%d |\r"), pNotifyInfo->pszUSBPortAddress, pNotifyInfo->nDownloadedPercent); +#endif + } + break; + case kProcDebugLog: + { +#if PRINTLOG + tprintf(_T("|%s: %s |\n"),pNotifyInfo->pszProcMsg,pNotifyInfo->pszUSBPortAddress); +#endif + } + break; + case kProcEraseAllFlash: + { +#if PRINTLOG + tprintf(_T("|%s:Erasing all flash percentage is:%d |\r"), pNotifyInfo->pszUSBPortAddress, pNotifyInfo->nDownloadedPercent); +#endif + } + break; + default: + break; + + } +#if PRINTLOG + if (!bIgnoreBlankLines) + { + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + tprintf(_T("\n")); + } +#endif + fflush(stdout); +} + +BOOL InitInstanceParams(PInstanceParams lpInstanceParam, struct StringList* pFbfList) +{ +#define KNEWSTR(ps,src) \ + ps = (kstring_t*)malloc(sizeof(kstring_t)); \ + ps->s = NULL;ps->l = ps->m = 0; \ + kstrcpy(ps, src); + + + //提取Dkb和DKBTimeheader + for (int i = 0; i < pFbfList->nSize; i++) + { + const char * strFile = pFbfList->strL[i]; + printf("Init %s\n",strFile); + if (strstr(strFile,_T("DKB_timheader.bin")) != NULL || strstr(strFile,_T("DKB_ntimheader.bin")) != NULL) + { + kstrcpy(&g_DkbTimPath,strFile); + for (int j = i; j < pFbfList->nSize-1; j++) + pFbfList->strL[j] = pFbfList->strL[j+1]; + i--; + pFbfList->nSize--; + } else if (strstr(strFile,_T("Dkb.bin"))) + { + kstrcpy(&g_DkbFilePath,strFile); + for (int j = i; j < pFbfList->nSize-1; j++) + pFbfList->strL[j] = pFbfList->strL[j+1]; + i--; + pFbfList->nSize--; + } + } +#if PRINTLOG + tprintf(_T("DKB_timheader is %s DKB is %s\n"),g_DkbTimPath.s, g_DkbFilePath.s); +#endif + //g_lpFbfImageList->sort(); + for (int i = 0; i < pFbfList->nSize-1; i++) + for (int j = i+1; j < pFbfList->nSize; j++) + if (strcmp(pFbfList->strL[i], pFbfList->strL[j]) > 0) + { + const char *strTmp = pFbfList->strL[i]; + pFbfList->strL[i] = pFbfList->strL[j]; + pFbfList->strL[j] = strTmp; + } + int ite = 0; + if (strstr(pFbfList->strL[ite],_T("0x")) != NULL ) + { + //Multi DDR case + while(ite!=pFbfList->nSize) + { + const char* tpos = strstr(pFbfList->strL[ite],_T("0x")); + if (tpos!= NULL) + { + DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC *pDDRFlashImagInfo = (pDDR_FLASH_DOWNLOADIMAGE_INFO_SPEC)malloc(sizeof(DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC)); + New_DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC(pDDRFlashImagInfo); + char buf[32]; + int ite2 = ite; + memset(buf, 0, sizeof(buf)); + strncpy(buf,tpos,6); + kstrcpy(&pDDRFlashImagInfo->sVendorDDRId,buf); + //pDDRFlashImagInfo->sVendorDDRId = ite->substr(tpos,6); + strncpy(buf,tpos+6,6); + + kstrcpy(&pDDRFlashImagInfo->sFlashInfo,buf); + //pDDRFlashImagInfo->sFlashInfo = ite->substr(tpos+6,6); + //tstring sDdrFlashInfo = ite->substr(tpos,12); + ite2++; + printf("VendorDDRId:%s FlashInfo:%s\n",pDDRFlashImagInfo->sVendorDDRId.s,pDDRFlashImagInfo->sFlashInfo.s); + if (strstr(pFbfList->strL[ite],_T("header")) != NULL) + { + kstring_t *kps; + KNEWSTR(kps,pFbfList->strL[ite2]) + *kl_pushf(pstrl, *pDDRFlashImagInfo->pImagelist) = kps; + KNEWSTR(kps,pFbfList->strL[ite]) + *kl_pushf(pstrl, *pDDRFlashImagInfo->pImagelist) = kps; + //pDDRFlashImagInfo->pImagelist->push_front(new tstring(*ite2)); + //pDDRFlashImagInfo->pImagelist->push_front(new tstring(*ite)); +#if PRINTLOG + printf("FBF head:%s FBF:%s\n",pFbfList->strL[ite],pFbfList->strL[ite2]); +#endif + } else + { + kstring_t *kps; + KNEWSTR(kps,pFbfList->strL[ite]) + *kl_pushf(pstrl, *pDDRFlashImagInfo->pImagelist) = kps; + KNEWSTR(kps,pFbfList->strL[ite2]) + *kl_pushf(pstrl, *pDDRFlashImagInfo->pImagelist) = kps; +#if PRINTLOG + printf("FBF head:%s FBF:%s\n",pFbfList->strL[ite2],pFbfList->strL[ite]); +#endif + } + //g_lpFbfImageList->erase(ite++); + //g_lpFbfImageList->erase(ite2++); + for (int k = ite; k < pFbfList->nSize-3; k+=2) + { + pFbfList->strL[k] = pFbfList->strL[k+2]; + pFbfList->strL[k+1] = pFbfList->strL[k+3]; + } + pFbfList->nSize -= 2; + pDDRFlashImagInfo->TotalFlashTypeNum = 1; + pDDRFlashImagInfo->TotalVendorDDRTypeNum = 1; + *kl_pushp(dfdil,*lpInstanceParam->pDownloadImagesList)=pDDRFlashImagInfo; + } + //pDDRFlashImagInfo->pImagelist->push_back(new tstring(*ite)); + ite = 0; + } + } else + { + DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC *pDDRFlashImagInfo = (pDDR_FLASH_DOWNLOADIMAGE_INFO_SPEC)malloc(sizeof(DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC)); + New_DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC(pDDRFlashImagInfo); + kstrcpy(&pDDRFlashImagInfo->sVendorDDRId,"Reserve"); + kstrcpy(&pDDRFlashImagInfo->sFlashInfo,"Reserve"); + int ite2 = ite; + ite2++; + kstring_t *kps; + if (strstr(pFbfList->strL[ite],_T("header")) != NULL ) + { + KNEWSTR(kps,pFbfList->strL[ite2]) + *kl_pushf(pstrl, *pDDRFlashImagInfo->pImagelist) = kps; + KNEWSTR(kps,pFbfList->strL[ite]) + *kl_pushf(pstrl, *pDDRFlashImagInfo->pImagelist) = kps; +#if PRINTLOG + printf("FBF head:%s FBF:%s\n",pFbfList->strL[ite],pFbfList->strL[ite2]); +#endif + } else{ + KNEWSTR(kps,pFbfList->strL[ite]) + *kl_pushf(pstrl, *pDDRFlashImagInfo->pImagelist) = kps; + KNEWSTR(kps,pFbfList->strL[ite2]) + *kl_pushf(pstrl, *pDDRFlashImagInfo->pImagelist) = kps; +#if PRINTLOG + printf("FBF head:%s FBF:%s\n",pFbfList->strL[ite2],pFbfList->strL[ite]); +#endif + } + for (int k = ite; k < pFbfList->nSize-4; k+=2) + { + pFbfList->strL[k] = pFbfList->strL[k+2]; + pFbfList->strL[k+1] = pFbfList->strL[k+3]; + } + pFbfList->nSize -= 2; + + pDDRFlashImagInfo->TotalFlashTypeNum = 1; + pDDRFlashImagInfo->TotalVendorDDRTypeNum = 1; + *kl_pushp(dfdil,*lpInstanceParam->pDownloadImagesList) = pDDRFlashImagInfo; + } + + + + TCHAR* pszTimFile = (TCHAR*)malloc(sizeof(TCHAR)*(g_DkbTimPath.l + 1)); + memset(pszTimFile, 0, (g_DkbTimPath.l + 1) * sizeof(TCHAR)); + memcpy(pszTimFile, g_DkbTimPath.s, g_DkbTimPath.l * sizeof(TCHAR)); + lpInstanceParam->pszDKBTim = pszTimFile; + + TCHAR* pszDkbFile = (TCHAR*)malloc(sizeof(TCHAR)*(g_DkbFilePath.l + 1)); + memset(pszDkbFile, 0, (g_DkbFilePath.l + 1) * sizeof(TCHAR)); + memcpy(pszDkbFile, g_DkbFilePath.s, g_DkbFilePath.l * sizeof(TCHAR)); + lpInstanceParam->pszDKBbin = pszDkbFile; + //lpInstanceParam->pDownloadImagesList->front()->pImagelist->back(); + kstring_t strFbfFile = *(*kl_back(pstrl, *kl_val(kl_begin(*lpInstanceParam->pDownloadImagesList))->pImagelist)); + BinFileWtp_OpenBinFile(&gBinFileWtp,_T("rb")); + // FILE* fpFile = _tfopen(strFbfFile.c_str(),_T("rb")); + // if (NULL == fpFile) + // { + // tprintf(_T("Open file failed:%s"),strFbfFile.c_str()); + // return FALSE; + // } + + MasterBlockHeader masterBlkHeader; + BinFileWtp_FseekBin(&gBinFileWtp,strFbfFile.s,4L,SEEK_SET); + BinFileWtp_ReadBinFile(&gBinFileWtp,&masterBlkHeader,sizeof(MasterBlockHeader),1,strFbfFile.s); + EndianConvertMasterBlockHeader(&masterBlkHeader); + printf("MasterBlkHeader.SizeOfBlock=%x\n",masterBlkHeader.Size_of_Block); + // fseek(fpFile,4,SEEK_SET); + // fread(&masterBlkHeader,sizeof(MasterBlockHeader),1,fpFile); + + DeviceHeader_V11 deviceHeaderBuf; + BinFileWtp_FseekBin(&gBinFileWtp,strFbfFile.s,masterBlkHeader.deviceHeaderOffset[0] + 4,SEEK_SET); + BinFileWtp_ReadBinFile(&gBinFileWtp,&deviceHeaderBuf,sizeof(DeviceHeader_V11),1,strFbfFile.s); + EndianConvertDeviceHeader_V11(&deviceHeaderBuf); + printf("deviceHeaderBuf.DeviceFlags=%x\n",deviceHeaderBuf.DeviceFlags); + // fseek(fpFile,masterBlkHeader.deviceHeaderOffset[0] + 4,SEEK_SET); + // fread(&deviceHeaderBuf,sizeof(DeviceHeader_V11),1,fpFile); + + lpInstanceParam->PlaformType = deviceHeaderBuf.ChipID; + lpInstanceParam->Commands |= (deviceHeaderBuf.FlashOpt.EraseAll?1:0); + lpInstanceParam->Commands |= (deviceHeaderBuf.FlashOpt.ResetBBT? (1<<2):0); + if (deviceHeaderBuf.FlashOpt.NandID) + { + lpInstanceParam->FlashType = 0; + } + /*Note: the BBCS and CRCS on/off are controlled by the blf via which fbf file was created. + Here for fbfdownloader pc side, just assume both are ON in order to avoid extract the information from TIMH. + The CallbackProc only try to read the infos when BBCS or CRCS success although the on/off at PC are always set to ON + lpInstanceParam->GetBadBlk = 1; + lpInstanceParam->ImageCrcEn = 1; + */ + lpInstanceParam->GetBadBlk = deviceHeaderBuf.BBCS_EN; + lpInstanceParam->ImageCrcEn = deviceHeaderBuf.CRCS_EN; + + BinFileWtp_CloseBinFIle(&gBinFileWtp); + // fclose(fpFile); + return TRUE; +#undef KNEWSTR +} + + +#ifdef STATICLIB_FBFDOWNLOAD +int fbfdownload(char * strBinFilePath, int nTimeout) +{ + struct StringList g_lpFbfImageList; + int i = 0; + BOOL bIsInProcess = FALSE; + memset(&g_lpFbfImageList,0,sizeof(struct StringList)); + //SetDebugMode(bDebugTrace); + pthread_mutex_init(&mutex, NULL); + pthread_cond_init(&cond, NULL); + +#if PRINTLOG + printf("\n\nfbfdownloader version: %s\n", pszSWDReleaseVersion); + printf("fbfdownloader date: %s\n\n", pszSWDReleaseDate); +#endif + //remove wtptp.ko + //system("rmmod wtptp.ko"); + if (nTimeout <= 0) + { + btimeoutset = FALSE; + }else + { + btimeoutset = TRUE; + timeout = nTimeout; + } + kstrcpy(&g_BinFilePath, strBinFilePath); + if (!IsFileExist(strBinFilePath)) + { + tprintf("BinFilePath Error\n"); + return 1; + } + + PInstanceParams lpInstanceParam = (PInstanceParams)malloc(sizeof(InstanceParams)); + if (NULL == lpInstanceParam) + { +#if PRINTLOG + tprintf("malloc memory failed.\n"); +#endif + return 1; + } + NewInstanceParams(lpInstanceParam); + if (g_BinFilePath.l > 0) + { + BinFileWtp_InitParameter2(&gBinFileWtp,g_BinFilePath.s, &g_lpFbfImageList); + } + + strDeviceDetectFile = GetAppPath(); + kputs("/swdl_linux_wtptp_device_detect.log", &strDeviceDetectFile); + + + if (bDownload) + { + if (InitInstanceParams(lpInstanceParam,&g_lpFbfImageList)) + { + lpInstanceParam->CallbackProc = CallbackProc; + if (bSingle) + { + lpInstanceParam->DownloadMode = 1; + } + if (!InitializeBL(lpInstanceParam)) + { +#if PRINTLOG + printf("InitializeBL failed , please check failed root cause....\n"); +#endif + DelInstanceParams(lpInstanceParam); + free(lpInstanceParam); + return 1; + } + bIsInProcess = TRUE; + } + else + { + DelInstanceParams(lpInstanceParam); + free(lpInstanceParam); + return 1; + } + + + } + + if (bIsInProcess) + { + if (bSingle) + { + if (btimeoutset) + { + struct timespec to; + pthread_mutex_lock(&mutex); + to.tv_sec = time(NULL) + timeout; + to.tv_nsec = 0; + if (ETIMEDOUT == pthread_cond_timedwait(&cond, &mutex, &to)) + { + exit_code = FAILED; + printf("swdl_linux timeout exit\n"); + printf("current timeout time is %d seconds, please increase timeout time to retry.\n", timeout); + } + + TerminateBL(); + } + else + { + pthread_mutex_lock(&mutex); + pthread_cond_wait(&cond, &mutex); + TerminateBL(); + } + printf("FBFDownloader EXIT.....\n"); + } + else + { + if (btimeoutset) + { + struct timespec to; + pthread_mutex_lock(&mutex); + to.tv_sec = time(NULL) + timeout; + to.tv_nsec = 0; + if (ETIMEDOUT == pthread_cond_timedwait(&cond, &mutex, &to)) + { + exit_code = FAILED; + printf("swdl_linux timeout exit\n"); + printf("current timeout time is %d seconds, please increase timeout time to retry.\n", timeout); + } + TerminateBL(); + } + else + { + + while (1) + { + sleep(2); + if (tolower(getchar()) == (int)'q') + { + TerminateBL(); + DelFile(strDeviceDetectFile.s); + DelInstanceParams(lpInstanceParam); + free(lpInstanceParam); + return 1; + } + } + } + } + } + DelFile(strDeviceDetectFile.s); + DelInstanceParams(lpInstanceParam); + free(lpInstanceParam); + return exit_code; +} +#else +int main(int argc, char *argv[]) +{ + struct StringList g_lpFbfImageList; + memset(&g_lpFbfImageList,0,sizeof(struct StringList)); + if (!ParseCommandLine(argc, argv)) + { +#if PRINTLOG + printf("Command line error.\n"); +#endif + + return 1; + } + if (already_running() == 1) + { + printf("\n\nthere is already an fbfdownloader is running, you can't run it again.\n\n"); + return 1; + } + int i = 0; + BOOL bIsInProcess = FALSE; + //SetDebugMode(bDebugTrace); + pthread_mutex_init(&mutex, NULL); + pthread_cond_init(&cond, NULL); + +#if PRINTLOG + printf("\n\nfbfdownloader version: %s\n", pszSWDReleaseVersion); + printf("fbfdownloader date: %s\n\n", pszSWDReleaseDate); +#endif + if (argc < MIN_ARGS) + { +#if PRINTLOG + tprintf(_T("Invalid parameters\n")); + tprintf(_T("Function: Do Remote or automatically Software Download to board\n")); + tprintf(_T("CommandLine: fbfdownloader -b BinFile [-p path of Log File]\n")); + tprintf(_T("Usage: FBFDownloader -b BinFile.bin \n\n")); +#endif + fflush(stdout); + + return 1; + } + + //remove wtptp.ko + //system("rmmod wtptp.ko"); + + + if (!IsFileExist(g_BinFilePath.s)) + { + tprintf("BinFilePath Error\n"); + return 1; + } + + + + PInstanceParams lpInstanceParam = (PInstanceParams)malloc(sizeof(InstanceParams)); + if (NULL == lpInstanceParam) + { +#if PRINTLOG + tprintf("malloc memory failed.\n"); +#endif + return 1; + } + NewInstanceParams(lpInstanceParam); + printf("BinFilePath is :%s\n",g_BinFilePath.s); + if (g_BinFilePath.l > 0) + { + if (FALSE == BinFileWtp_InitParameter2(&gBinFileWtp,g_BinFilePath.s, &g_lpFbfImageList)) + { + printf("BinFileWtp_InitParameter2 Faile!\n"); + return FAILED; + } else + { + printf("BinFileWtp_InitParameter2 Success!\n"); + } + } + strDeviceDetectFile = GetAppPath(); + //kputs("/swdl_linux_wtptp_device_detect.log", &strDeviceDetectFile); + printf("AppPath is :%s\n",strDeviceDetectFile.s); + if (bDownload) + { + if (InitInstanceParams(lpInstanceParam, &g_lpFbfImageList)) + { + lpInstanceParam->CallbackProc = CallbackProc; + if (bSingle) + { + lpInstanceParam->DownloadMode = 1; + } + if (!InitializeBL(lpInstanceParam)) + { +#if PRINTLOG + printf("InitializeBL failed , please check failed root cause....\n"); +#endif + DelInstanceParams(lpInstanceParam); + free(lpInstanceParam); + return 1; + } + bIsInProcess = TRUE; + } + else + { + DelInstanceParams(lpInstanceParam); + free(lpInstanceParam); + return 1; + } + + + } + + if (bIsInProcess) + { + if (bSingle) + { + if (btimeoutset) + { + struct timespec to; + pthread_mutex_lock(&mutex); + to.tv_sec = time(NULL) + timeout; + to.tv_nsec = 0; + if (ETIMEDOUT == pthread_cond_timedwait(&cond, &mutex, &to)) + { + exit_code = FAILED; + printf("swdl_linux timeout exit\n"); + printf("current timeout time is %d seconds, please increase timeout time to retry.\n", timeout); + } + + TerminateBL(); + } + else + { + pthread_mutex_lock(&mutex); + pthread_cond_wait(&cond, &mutex); + TerminateBL(); + } + printf("FBFDownloader EXIT.....\n"); + } + else + { + if (btimeoutset) + { + struct timespec to; + pthread_mutex_lock(&mutex); + to.tv_sec = time(NULL) + timeout; + to.tv_nsec = 0; + if (ETIMEDOUT == pthread_cond_timedwait(&cond, &mutex, &to)) + { + exit_code = FAILED; + printf("swdl_linux timeout exit\n"); + printf("current timeout time is %d seconds, please increase timeout time to retry.\n", timeout); + } + TerminateBL(); + } + else + { + + while (1) + { + sleep(2); + if (tolower(getchar()) == (int)'q') + { + TerminateBL(); + DelFile(strDeviceDetectFile.s); + DelInstanceParams(lpInstanceParam); + free(lpInstanceParam); + return 1; + } + } + } + } + } + DelFile(strDeviceDetectFile.s); + DelInstanceParams(lpInstanceParam); + free(lpInstanceParam); + return exit_code; +} +#endif diff --git a/fbfdownloader/src/FBFDownloader_makefile b/fbfdownloader/src/FBFDownloader_makefile new file mode 100644 index 00000000..286862ac --- /dev/null +++ b/fbfdownloader/src/FBFDownloader_makefile @@ -0,0 +1,47 @@ +############################################################### +# Makefile for the Marvell download for MMP2/wukong/NEVO on linux platform. +# +# +############################################################## + + +CC = gcc -static +BASE:=$(shell pwd) +IFL_PATH = ./ +IFL_INCLUDE_DIR = $(IFL_PATH)/ +IFL_LIBRARY_DIR = $(IFL_PATH) + +TBBOBJS = CommonFun.o\ + ParaDefine.o\ + WTPCOMMCLASS.o\ + BinFileWtp.o\ + WtptpDownloader.o\ + WtptpDownLoad.o\ + ConvetEdian.o\ + BulkDevNonDrv_Linux.o\ + kstring.o\ + FBFDownloader.o\ + +CCFLAGS += -O2 -D LINUX=1 -D WINDOWS=0 -D DEBUG_MODE=0 -D PRINTLOG=1 -std=c99 + +LIBS = -lpthread + + + +CCFLAGS += -D TRUSTED_BOOT=1 -I $(IFL_INCLUDE_DIR) +OUTPUT = fbfdownloader + + +OBJS = $(TBBOBJS) + +all: $(OBJS) + $(CC) -g -o $(OUTPUT) $(OBJS) $(LIBS) -ldl + -rm *.o + +$(TBBOBJS): %.o: $(BASE)/%.c + $(CC) -g $(CCFLAGS) -c $(BASE)/$*.c -o $(BASE)/$*.o + +.PHONY: clean tar tar-% +clean: + -rm *.o $(OUTPUT) + diff --git a/fbfdownloader/src/FBFDownloader_makefile_android b/fbfdownloader/src/FBFDownloader_makefile_android new file mode 100644 index 00000000..5dc04a07 --- /dev/null +++ b/fbfdownloader/src/FBFDownloader_makefile_android @@ -0,0 +1,55 @@ +############################################################### +# Makefile for the Marvell download for MMP2/wukong/NEVO on linux platform. +# +# +############################################################## + + +#CC = arm_1103_le-g++ -static +#CC = mipsel-linux-uclibc-g++ -static +#CC = mipsel-openwrt-linux-g++ -static +#CC = arm-hisiv200-linux-gnueabi-g++ --static + +CC = ${CROSS}gcc #-static +BASE:=$(shell pwd) +IFL_PATH = ./ +IFL_INCLUDE_DIR = $(IFL_PATH)/ +IFL_LIBRARY_DIR = $(IFL_PATH) + +TBBOBJS = CommonFun.o\ + ParaDefine.o\ + WTPCOMMCLASS.o\ + BinFileWtp.o\ + WtptpDownloader.o\ + WtptpDownLoad.o\ + ConvetEdian.o\ + BulkDevNonDrv_Linux.o\ + kstring.o\ + FBFDownloader.o\ + +CCFLAGS += -O2 -D LINUX=1 -D WINDOWS=0 -D DEBUG_MODE=0 -D PRINTLOG=1 -std=c99 -fPIE + + LIBS = -lc + + + +CCFLAGS += -D TRUSTED_BOOT=1 -I $(IFL_INCLUDE_DIR) +OUTPUT = fbfdownloader_cross + + +OBJS = $(TBBOBJS) + +all: $(OBJS) + $(CC) -g -o $(OUTPUT) $(OBJS) $(LIBS) -ldl -fPIE -pie + -rm *.o + +$(TBBOBJS): %.o: $(BASE)/%.c + $(CC) -g $(CCFLAGS) -c $(BASE)/$*.c -o $(BASE)/$*.o + +.PHONY: clean +clean: + -rm *.o $(OUTPUT) + + + + diff --git a/fbfdownloader/src/FBFDownloader_makefile_cross b/fbfdownloader/src/FBFDownloader_makefile_cross new file mode 100644 index 00000000..527e39c3 --- /dev/null +++ b/fbfdownloader/src/FBFDownloader_makefile_cross @@ -0,0 +1,55 @@ +############################################################### +# Makefile for the Marvell download for MMP2/wukong/NEVO on linux platform. +# +# +############################################################## + + +#CC = arm_1103_le-g++ -static +#CC = mipsel-linux-uclibc-g++ -static +#CC = mipsel-openwrt-linux-g++ -static +#CC = arm-hisiv200-linux-gnueabi-g++ --static + +CC = ${CROSS}gcc #-static +BASE:=$(shell pwd) +IFL_PATH = ./ +IFL_INCLUDE_DIR = $(IFL_PATH) +IFL_LIBRARY_DIR = $(IFL_PATH) + +TBBOBJS = CommonFun.o\ + ParaDefine.o\ + WTPCOMMCLASS.o\ + BinFileWtp.o\ + WtptpDownloader.o\ + WtptpDownLoad.o\ + ConvetEdian.o\ + BulkDevNonDrv_Linux.o\ + kstring.o\ + FBFDownloader.o\ + +CCFLAGS += -O2 -D LINUX=1 -D WINDOWS=0 -D DEBUG_MODE=0 -D PRINTLOG=1 -std=gnu99 + + LIBS = -lpthread -lc -lgcc_eh + + + +CCFLAGS += -D TRUSTED_BOOT=1 -I $(IFL_INCLUDE_DIR) +OUTPUT = fbfdownloader_cross + + +OBJS = $(TBBOBJS) + +all: $(OBJS) + $(CC) -g -o $(OUTPUT) $(OBJS) $(LIBS) -ldl + -rm *.o + +$(TBBOBJS): %.o: $(BASE)/%.c + $(CC) -g $(CCFLAGS) -c $(BASE)/$*.c -o $(BASE)/$*.o + +.PHONY: clean +clean: + -rm *.o $(OUTPUT) + + + + diff --git a/fbfdownloader/src/Macrodef.h b/fbfdownloader/src/Macrodef.h new file mode 100644 index 00000000..7ce15665 --- /dev/null +++ b/fbfdownloader/src/Macrodef.h @@ -0,0 +1,141 @@ +#pragma once +#pragma warning ( disable : 4100 ) // Disable warning messages: unreferenced formal parameter +#pragma warning ( disable : 4189 ) // Disable warning messages: local variable is initialized but not referenced +#include +#include +#include +#include "klist.h" +#include "kstring.h" +#ifdef LINUX +#include +#if defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) +#define htobe16(x) (x) +#define htobe32(x) (x) +#define htobe64(x) (x) +#define htole16(x) __builtin_bswap16(x) +#define htole32(x) __builtin_bswap32(x) +#define htole64(x) __builtin_bswap64(x) +#else +#define htobe16(x) __builtin_bswap16(x) +#define htobe32(x) __builtin_bswap32(x) +#define htobe64(x) __builtin_bswap64(x) +#define htole16(x) (x) +#define htole32(x) (x) +#define htole64(x) (x) +#endif /* __BYTE_ORDER__ */ +#define be16toh(x) htobe16(x) +#define le16toh(x) htole16(x) +#define be32toh(x) htobe32(x) +#define le32toh(x) htole32(x) +#define be64toh(x) htobe64(x) +#define le64toh(x) htole64(x) + +#include +#include +#include +#include +#include + +#define _tmain main +#define _TCHAR TCHAR +#define _fseeki64 fseeko +#ifndef VOID +#define VOID void +typedef char CHAR; +typedef short SHORT; +typedef long LONG; +#endif + +#undef FALSE +#undef TRUE +#undef NULL +#define FALSE 0 +#define TRUE 1 +#define NULL 0 + +#ifdef UNICODE +#define _T L## +#define TCHAR wchar_t +#define _tprintf wprintf +#define _tcslen wcslen +#define tsnprintf snwprintf +#define _tcslen wcslen +#define _tcscmp wcscmp +#define _tfopen _wfopen +#define _tcsstr wcsstr +#define _tcscat wcscat +#define _taccess access +#define _tcstoul wcstoul +#define _tcsrchr wcsrchr +#define _tcscpy wcscpy +#define _tcsncpy wcsncpy +#define _ttoi _wtoi +#define _ttot _itow +#define _vstprintf vswprintf +#define _trename _wrename +#define _tremove _wremove +#define _stscanf swscanf +#else +#define _T +#define TCHAR char +#define _tprintf printf +#define _tcslen strlen +#define tsnprintf snprintf +#define _tcslen strlen +#define _tcscmp strcmp +#define _tfopen fopen +#define _tcsstr strstr +#define _tcscat strcat +#define _taccess access +#define _tcstoul strtoul +#define _tcsrchr strrchr +#define _tcscpy strcpy +#define _tcsncpy strncpy +#define _ttoi atoi +#define _ttot itoa +#define _vstprintf vsprintf +#define _trename rename +#define _tremove remove +#define _stscanf sscanf +#endif + +#else +#ifdef UNICODE +#define tsnprintf _snwprintf +#else +#define tsnprintf _snprintf +#endif +#endif + + +#ifdef UNICODE +#define tsprintf swprintf +#define taccess _waccess +#define tatoi _wtoi +#define titoa _itow +#define tsscanf swscanf +#define ttolower towlower +#define ttoupper towupper +#define tfprintf fwprintf +#define tprintf wprintf + +#define t_splitpath_s _wsplitpath_s + +#else +#define tsprintf sprintf +#define taccess access +#define tatoi atoi +#define titoa itoa +#define tsscanf sscanf +#define ttolower tolower +#define ttoupper toupper +#define tfprintf fprintf +#define tprintf printf +#define t_splitpath_s _splitpath_s +#endif + + +#define ACCESS_FILE_EXIST 0 +#define COMPARE_EQUAL 0 + + diff --git a/fbfdownloader/src/Makefile b/fbfdownloader/src/Makefile new file mode 100644 index 00000000..527e39c3 --- /dev/null +++ b/fbfdownloader/src/Makefile @@ -0,0 +1,55 @@ +############################################################### +# Makefile for the Marvell download for MMP2/wukong/NEVO on linux platform. +# +# +############################################################## + + +#CC = arm_1103_le-g++ -static +#CC = mipsel-linux-uclibc-g++ -static +#CC = mipsel-openwrt-linux-g++ -static +#CC = arm-hisiv200-linux-gnueabi-g++ --static + +CC = ${CROSS}gcc #-static +BASE:=$(shell pwd) +IFL_PATH = ./ +IFL_INCLUDE_DIR = $(IFL_PATH) +IFL_LIBRARY_DIR = $(IFL_PATH) + +TBBOBJS = CommonFun.o\ + ParaDefine.o\ + WTPCOMMCLASS.o\ + BinFileWtp.o\ + WtptpDownloader.o\ + WtptpDownLoad.o\ + ConvetEdian.o\ + BulkDevNonDrv_Linux.o\ + kstring.o\ + FBFDownloader.o\ + +CCFLAGS += -O2 -D LINUX=1 -D WINDOWS=0 -D DEBUG_MODE=0 -D PRINTLOG=1 -std=gnu99 + + LIBS = -lpthread -lc -lgcc_eh + + + +CCFLAGS += -D TRUSTED_BOOT=1 -I $(IFL_INCLUDE_DIR) +OUTPUT = fbfdownloader_cross + + +OBJS = $(TBBOBJS) + +all: $(OBJS) + $(CC) -g -o $(OUTPUT) $(OBJS) $(LIBS) -ldl + -rm *.o + +$(TBBOBJS): %.o: $(BASE)/%.c + $(CC) -g $(CCFLAGS) -c $(BASE)/$*.c -o $(BASE)/$*.o + +.PHONY: clean +clean: + -rm *.o $(OUTPUT) + + + + diff --git a/fbfdownloader/src/ParaDefine.c b/fbfdownloader/src/ParaDefine.c new file mode 100644 index 00000000..79e1f380 --- /dev/null +++ b/fbfdownloader/src/ParaDefine.c @@ -0,0 +1,161 @@ +#include "ParaDefine.h" +#include "BinFileWtp.h" +#include "WtptpDownloader.h" + +extern kstring_t strDeviceDetectFile, g_DkbFilePath,g_DkbTimPath,g_BinFilePath; +void Copy_NotifyStatus(PProcInfo me,struct _NotifyStatus* rhs) +{ + me->nDevice = rhs->nDevice; + me->nDevType = rhs->nDevType; + me->nDownloadedPercent = rhs->nDownloadedPercent; + me->lpBadBlk = rhs->lpBadBlk; + me->lpImageCrc = rhs->lpImageCrc; + me->eProcState = rhs->eProcState; + me->eProcStatus = rhs->eProcStatus; + me->nErrorCode = rhs->nErrorCode; + memcpy(&me->pszProcMsg,&rhs->pszProcMsg,sizeof(me->pszProcMsg)); + memcpy(&me->pszUSBPortAddress,&rhs->pszUSBPortAddress,sizeof(me->pszUSBPortAddress)); +} + +void New_DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC(pDDR_FLASH_DOWNLOADIMAGE_INFO_SPEC me) +{ + me->pImagelist = (t_stringList*)malloc(sizeof(t_stringList)); + *me->pImagelist = kl_init(pstrl); + ks_release(&me->sVendorDDRId); + ks_release(&me->sFlashInfo); + me->TotalVendorDDRTypeNum = 0; + me->TotalFlashTypeNum = 1; +} + +void Del_DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC(pDDR_FLASH_DOWNLOADIMAGE_INFO_SPEC me) +{ + + if( me->pImagelist!=NULL) + { + t_stringListIter ImagesIter = kl_begin(*me->pImagelist); + while(ImagesIter!= kl_end(*me->pImagelist) ) + { + if (kl_val(ImagesIter)->s) + free(kl_val(ImagesIter)->s); + free(kl_val(ImagesIter)); + ImagesIter = kl_next(ImagesIter); + } + kl_destroy(pstrl, *me->pImagelist); + free(me->pImagelist); + me->pImagelist = NULL; + } + if (me->sFlashInfo.s) + free(me->sFlashInfo.s); + if (me->sVendorDDRId.s) + free(me->sVendorDDRId.s); + ks_release(&me->sFlashInfo); + ks_release(&me->sVendorDDRId); +} + +void Copy_DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC(pDDR_FLASH_DOWNLOADIMAGE_INFO_SPEC me,struct _DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC* DDRFlashDownloadImageInfo) +{ + #define KNEWSTR(ps,src) \ + ps = (kstring_t*)malloc(sizeof(kstring_t)); \ + ps->s = NULL;ps->l = ps->m = 0; \ + kstrcpy(ps, src); + for(t_stringListIter ite = kl_begin(*me->pImagelist); ite != kl_end(*me->pImagelist); ite = kl_next(ite)) + { + if (kl_val(ite)->s) + free(kl_val(ite)->s); + free( kl_val(ite)); + } + kl_clear(pstrl,*me->pImagelist); + + me->sVendorDDRId = DDRFlashDownloadImageInfo->sVendorDDRId; + me->sFlashInfo = DDRFlashDownloadImageInfo->sFlashInfo; + me->TotalVendorDDRTypeNum = DDRFlashDownloadImageInfo->TotalVendorDDRTypeNum; + me->TotalFlashTypeNum = DDRFlashDownloadImageInfo->TotalFlashTypeNum; + t_stringListIter ImagesIter = kl_begin(*DDRFlashDownloadImageInfo->pImagelist); + while(ImagesIter!= kl_end(*DDRFlashDownloadImageInfo->pImagelist) ) + { + kstring_t *kps; + KNEWSTR(kps,kl_val(ImagesIter)->s); + *kl_pushp(pstrl,*me->pImagelist) = kps; + ImagesIter = kl_next(ImagesIter); + } + #undef KNEWSTR +} + + +void Copy_WTPTPREAMBLECOMMAND(pWTPTPREAMBLECOMMAND me,struct _WTPTPREAMBLECOMMAND* WTPCMD) +{ + me->CMD = WTPCMD->CMD; + me->SEQ = WTPCMD->SEQ; + me->CID = WTPCMD->CID; + me->Flags = WTPCMD->Flags; + me->LEN = WTPCMD->LEN; + memcpy(WTPCMD->Data,me->Data,CMDDATALENGTH); +} + + +void DelInstanceParams(PInstanceParams me) +{ + if (NULL != me->pszDKBbin) {free((void*)me->pszDKBbin);me->pszDKBbin = NULL;} + if (NULL != me->pszDKBTim) {free((void*)me->pszDKBTim);me->pszDKBTim = NULL;} + if (NULL != me->pszOBMFile) {free((void*)me->pszOBMFile);me->pszOBMFile = NULL;} + if (NULL != me->pszWTMFile) {free((void*)me->pszWTMFile);me->pszWTMFile = NULL;} + if (NULL != me->pszJTAGKeyFile) {free((void*)me->pszJTAGKeyFile);me->pszJTAGKeyFile = NULL;} + if (NULL != me->pszTZIIFile) {free((void*)me->pszTZIIFile);me->pszTZIIFile = NULL;} + if (NULL != me->pWtptpPreaCmd){free((void*)me->pWtptpPreaCmd); me->pWtptpPreaCmd = NULL;} + if (NULL != me->pUploadSpecs) + { + for (t_UpLoadDataSpecIter iter = kl_begin(*me->pUploadSpecs);iter != kl_end(*me->pUploadSpecs);iter = kl_next(iter)) + { + free( kl_val(iter)); + } + free( me->pUploadSpecs); + me->pUploadSpecs = NULL; + } + + if (NULL != me->pDownloadImagesList) + { + for (t_DdrFlashDownloadImgInfoIter iter = kl_begin(*me->pDownloadImagesList);iter != kl_end(*me->pDownloadImagesList);iter = kl_next(iter)) + { + Del_DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC(kl_val(iter)); + free( kl_val(iter)); + } + } + kl_destroy(dfdil, *me->pDownloadImagesList); + free( me->pDownloadImagesList); + DelCWtptpDownLoad(&gWtptpDownload); + BinFileWtp_DelMe(&gBinFileWtp); + + //global var + free(strDeviceDetectFile.s); + free(g_DkbFilePath.s); + free(g_DkbTimPath.s); + free(g_BinFilePath.s); +} +void NewInstanceParams(PInstanceParams me) +{ + me->pszDKBbin=NULL; + me->pszDKBTim= NULL; + me->CallbackProc=NULL; + me->pszOBMFile=NULL; + me->pszWTMFile=NULL; + me->pszJTAGKeyFile=NULL; + me->pszTZIIFile=NULL; + me->pUploadSpecs=NULL; + me->pWtptpPreaCmd=NULL; + me->Commands=0; + me->FlashType=5; + me->PlaformType=4; + me->FlashPageSize=0; + me->DownloadMode=0; + me->ProductionMode=0; + me->GetBadBlk=0; + me->ImageCrcEn=0; + me->ReservedVal[0] = BADBLOCKRATE_BASE*100;//坏块率默认值 + me->pDownloadImagesList = (t_DdrFlashDownloadImgInfoList*)malloc(sizeof(t_DdrFlashDownloadImgInfoList)); + (*me->pDownloadImagesList) = kl_init(dfdil); + memset(&gBinFileWtp, 0, sizeof(struct CBinFileWtp)); + BinFileWtp_ResetPara(&gBinFileWtp); + memset(&gWtptpDownload, 0, sizeof(struct CWtptpDownLoad)); + NewCWtptpDownLoad(&gWtptpDownload); +} + diff --git a/fbfdownloader/src/ParaDefine.h b/fbfdownloader/src/ParaDefine.h new file mode 100644 index 00000000..4373321a --- /dev/null +++ b/fbfdownloader/src/ParaDefine.h @@ -0,0 +1,774 @@ +#ifndef PARADEFINE_H +#define PARADEFINE_H + +#include "./Macrodef.h" +#include "./Typedef.h" +#include "ErrorCode.h" +#include "./UploadParaDef.h" +#include "kstring.h" +#define BADBLOCKRATE_BASE 10000 + +extern struct CWtptpDownLoad gWtptpDownload; +extern struct CBinFileWtp gBinFileWtp; + + +#define __pstrl_free(x) +KLIST_INIT(pstrl,kstring_t*,__pstrl_free) + + +struct StringList +{ + const char* strL[64]; + int nSize; +}; + +typedef struct +{ + UINT32 ImageID; + UINT32 BadCnt; +}ImageBBInfo; + +typedef struct +{ + UINT32 ImageID; + UINT32 CRC32; +}CRCInfo; + +// Badblock data +typedef struct { + UINT32 TotalBadBlocks; + UINT32 TotalBlocks; + ImageBBInfo BadCount[8]; //reserved for critical partitions support +} BadBlockData, *pBadBlockData; + +// Image CRC data +typedef struct +{ + UINT32 MCPID; + UINT32 ImageNum; + CRCInfo ImageCRC[32]; //Crc32 of all images, support 32 images at maximum +}ImageCRCInfo, *pImageCRCInfo; + + +typedef enum EProcessState +{ + kProcIdle = 0, // Not active + kProcInit = 1, // Initialization + kProcBootRom = 2, // Initialization for BootRom + kProcPrepareData = 3, // Preparation images downloading + kProcConnecting = 4, // Open connection and handshake + kProcDownloading = 5, // Downloading Data + kProcAborting = 6, // Aborting in process + kProcFileCompleted = 7, // File downloading process is completed + kProcCompleted = 8, // Downloading process is completed + kProcUsbRemove = 9, // Usb device is removed + kProcDebugLog = 10, // Debug message report + kProcBurningFlash = 11, // Burning Data + kProcUploadingData = 12, // Uploading Data + kProcWaitingUploadData = 13, // Waiting UE to get upload data + kProcEraseAllFlash = 14, // Erase all Flash + kProcErrorCode = 15, // Error code in downloading + kProcFuseInfo = 16, // fuse Info + kProcFuseInfoError = 17, // fuse Info operate error report + kProcUEInfo = 18, // fuse Info + kProcStateMax = 0xfe +}eProcessState; + + +typedef enum +{ + stOK, // Finished OK + stInvalid, // Couldn't create instance + stUsbError, // Couldn't connect to the USB driver + stNoReply, // Target is not responding + stBadReply, // Protocol error + stDownloadMBError, // Downloading error + stFailedToConnect, // Handshake failure/TimeOut + stFailedFileCreate, // Create file failed + stParseFile, // Parse file error + stEmptyFileList, // Image file list is empty + stFileError, // AXF file not found or file format error + stFilePathError, // File path is not exist + stAborted, // Aborted using abort Process() + stThreadError, // Error creating the instance thread + stNack, // Not acknowledge + stCalculationError, // Check sum calculation error + stImgConversionFail, // Error Image conversion + stImgCheckOverlapFail, // Error image overlap + stImgBuildFail, // Error image build + stFolderError, // Work folder error + stMepBndError, // Error binding Mep data + stBurningFlashError, // Error in burning flash + stUEErrorTrace = 0xff // Target error trace +} eProcessStatus; + + +//Providing process evaluation information via Callback function +typedef struct _NotifyStatus +{ + int nDevice, // Active device number + nDevType, // Device type kUnknown = 0, kBootRom = 1, kBootloader = 2 + nDownloadedPercent; // Downloading percent + TCHAR pszProcMsg[1024]; // Callback message + TCHAR pszUSBPortAddress[260]; // USB socket address + BadBlockData lpBadBlk; // flash bad block data + ImageCRCInfo lpImageCrc; // CRC value of Images read back from flash + eProcessState eProcState; // Current process state + eProcessStatus eProcStatus; // Current process status + int nErrorCode; // Errorcode in download or burning + + + +}NotifyStatus, *PProcInfo; + + +typedef void (/*__stdcall*/ * CALLBACKPROC)(PProcInfo pNotifyInfo); + + +typedef klist_t(pstrl)* t_stringList; +typedef kliter_t(pstrl)* t_stringListIter; + +typedef struct _DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC +{ + t_stringList* pImagelist; + kstring_t sVendorDDRId; + kstring_t sFlashInfo; + int TotalVendorDDRTypeNum; + int TotalFlashTypeNum; +} DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC,*pDDR_FLASH_DOWNLOADIMAGE_INFO_SPEC; + + +#define __dfdi_free(x) +KLIST_INIT(dfdil,DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC*,__dfdi_free) + + +typedef klist_t(dfdil)* t_DdrFlashDownloadImgInfoList; +typedef kliter_t(dfdil)* t_DdrFlashDownloadImgInfoIter; + +#define CMDDATALENGTH 8196 +typedef struct _WTPTPREAMBLECOMMAND +{ + BYTE CMD; + BYTE SEQ; + BYTE CID; + BYTE Flags; + UINT32 LEN; + BYTE Data[CMDDATALENGTH]; + +}WTPTPREAMBLECOMMAND,*pWTPTPREAMBLECOMMAND; + + + + + +#define CFG_VERSION _T("V1.3") +#define CFG_SECTION_NAME _T("DownloadPackageCfg") +#define CFG_VERSION_NUMBER _T("CfgVersion") +#define CFG_IMAGE_NUM _T("ImageNum") +#define CFG_FBF_SET_NUM _T("FbfSetNum") +#define CFG_DDRTYPE_NUM _T("DDRVendorTypeNum") +#define CFG_FLASHTYPE_NUM _T("FlashTypeNum") +#define CFG_IMAGE_IDX _T("Image_") +#define CFG_DDREMMC_TYPE _T("DDRVendorID_EMMC") +#define CFG_DDRTYPE_NAME _T("DDRVendorName") +#define CFG_DDRTYPE_ID _T("DDRVendorID") +#define CFG_FLASH_INFO _T("FlashInfo") +#define CFG_DKB_BIN _T("DKBbin") +#define CFG_DKB_TIM _T("DKBTim") +#define CFG_OBM_FILE _T("OBMFile") +#define CFG_TZII_FILE _T("TZIIFile") +#define CFG_WTM_FILE _T("WTMFile") +#define CFG_IMEI_FILE _T("IMEIFile") +#define CFG_MEP_FILE _T("MEPFile") +#define CFG_PLATFORM_TYPE _T("PlatFormType") +#define CFG_FLASH_TYPE _T("FlashFamilyType") +#define CFG_COMMAND _T("Command") +#define CFG_FLASH_PAGE_SIZE _T("FlashPageSize") +#define CFG_PRODUCTIONMODE _T("ProductionMode") + +#define MAX_RESERVED_DATA 4 + +typedef struct _InstanceParams +{ + t_DdrFlashDownloadImgInfoList * pDownloadImagesList; + const TCHAR* pszDKBbin; // Download file for Bootrom + const TCHAR* pszDKBTim; // Primary flasher file path(*.bin, *.axf, *.elf) (can be either Comm. or App flasher) + const TCHAR* pszOBMFile; // OBM file path + const TCHAR* pszWTMFile; // WTM file path + const TCHAR* pszTZIIFile; //TZII file path + const TCHAR* pszJTAGKeyFile; // OEM Key file path to do re-eanble JTAG in case JTAG is disable + CALLBACKPROC CallbackProc; // Callback function that will back relevant process information + pWTPTPREAMBLECOMMAND pWtptpPreaCmd; // Customize Preamble Command + unsigned int PlaformType; /* 2-MMP2 */ + /* 3-WUKONG */ + /* 4-PXA978 */ + /* 5-MMP3 */ + /* 6-PXA1802 */ + /* 8-PXA988/986 */ + /* 9-PXA1088 */ + /* 10-PXA1928 */ + /* 11-PXA1920 */ + /* 15-PXA1826 */ + unsigned int FlashType; // 0-NAND, 1-eMMC,3-SPINOR,4-ONENAND,others-Unknown + unsigned int Commands; // flags description /* bit switches */, user only need to set bit3 if user want to use customized preamble + /*bit 0:Erase all flash flag*/ + /*bit 1: Upload flag */ + /*bit 2: Reset BBT flag */ + /*bit 3: Customized preamble flag*/ + /*bit 4: erase all flash only flag */ + /*bit 5: JTAG Re enable flag */ + /*bit 6 ~ bit31 reserved */ + unsigned int FlashPageSize; // Nand Flash Data page size + unsigned int DownloadMode; // Single_Download 1,multi_download 0; + unsigned int ProductionMode; // ; + unsigned int GetBadBlk; //get flash bad block enabled 1; otherwise: 0 + unsigned int ImageCrcEn; // Image CRC enabled: 1,Image CRC disabled: 0; + unsigned int ReservedVal[MAX_RESERVED_DATA]; + t_UpLoadDataSpecList* pUploadSpecs; // Upload spec Info + +}InstanceParams, *PInstanceParams; + +#ifndef COMPRESSDATA +static ERRORCODETABLE WTPTPErrorCodes[MAXERRORCODES]= +{ + {NoError,_T("NoError")}, + {NotFoundError,_T("NotFoundError")}, + {GeneralError,_T("GeneralError")}, + {WriteError,_T("WriteError")}, + {ReadError,_T("ReadError")} , + {NotSupportedError,_T("NotSupportedError")} , + {InvalidPlatformConfigError,_T("InvalidPlatformConfigError")}, + {InvalidPlatformState,_T("InvalidPlatformState")}, + {InvalidSizeError,_T("InvalidSizeError")}, + {ProbeListExhaustError,_T("ProbeListExhaustError")}, + {DDR_NotInitializedError,_T("DDR_NotInitializedError")}, + {UnknownReservedPackage,_T("UnknownReservedPackage")}, + {NULLPointer,_T("NULLPointer")}, + {NANDIDDISMATCH ,_T("NANDIDDISMATCH")}, + {FBF_VersionNotMatch,_T("FBF_VersionNotMatch")}, + {FBF_DeviceMoreThanOne,_T("FBF_DeviceMoreThanOne")}, + {PlatformConfigBuckError,_T("PlatformConfigBuckError")}, + {ChipIdMismatch,_T("ChipIdMismatch")}, + {EraseError,_T("EraseError ")}, + {ProgramError,_T("ProgramError")}, + {InvalidBootTypeError,_T("InvalidBootTypeError")}, + {ProtectionRegProgramError,_T("ProtectionRegProgramError")}, + {NoOTPFound,_T("NoOTPFound")}, + {BBTReadError,_T("BBTReadError")}, + {MDOCInitFailed,_T("MDOCInitFailed ")}, + {OneNandInitFailed,_T("OneNandInitFailed")}, + {MDOCFormatFailed,_T("MDOCFormatFailed ")}, + {BBTExhaustedError,_T("BBTExhaustedError ")}, + {NANDNotFound,_T("NANDNotFound ")}, + {SDMMCNotFound,_T("SDMMCNotFound ")}, + {FlexOneNANDNotFound,_T("FlexOneNANDNotFound ")}, + {SDMMCReadError,_T("SDMMCReadError ")}, + {XIPReadError,_T("XIPReadError ")}, + {FlexOneNANDError,_T("FlexOneNANDError ")}, + {FlashDriverInitError,_T("FlashDriverInitError")}, + {FlashFuncNotDefined,_T("FlashFuncNotDefined")}, + {OTPError,_T("OTPError")}, + {InvalidAddressRangeError,_T("InvalidAddressRangeError")}, + {FlashLockError,_T("FlashLockError ")}, + {ReadDisturbError,_T("ReadDisturbError")}, + {FlashReadError,_T("FlashReadError")}, + {SPIFlashNotResponding,_T("SPIFlashNotResponding")}, + {ImageOverlayError,_T("ImageOverlayError ")}, + {FlashAddrNotChunkAlign ,_T("FlashAddrNotChunkAlign")}, + {FlashAddrNotWordAlign ,_T("FlashAddrNotWordAlign")}, + {BBTOUTOFRANGE ,_T("BBTOUTOFRANGE")}, + {FlashWriteVerifyError ,_T("FlashWriteVerifyError")}, + {FlashAddrOutOfRange ,_T("FlashAddrOutOfRange")}, + {DFCDoubleBitError,_T("DFCDoubleBitError ")}, + {DFCSingleBitError,_T("DFCSingleBitError ")}, + {DFCCS0BadBlockDetected,_T("DFCCS0BadBlockDetected ")}, + {DFCCS1BadBlockDetected,_T("DFCCS1BadBlockDetected ")}, + {DFCInitFailed,_T("DFCInitFailed")}, + {DFCONFIConfigError,_T("DFCONFIConfigError")}, + {DFC_WRREQ_TO,_T("DFC_WRREQ_TO")}, + {DFC_WRCMD_TO,_T("DFC_WRCMD_TO")}, + {DFC_RDDREQ_TO,_T("DFC_RDDREQ_TO")} , + {DFC_RDY_TO,_T("DFC_RDY_TO ")}, + {DFCCS0CommandDoneError,_T("DFCCS0CommandDoneError")}, + {DFCCS1CommandDoneError,_T("DFCCS1CommandDoneError ")}, + {DFC_PGDN_TO,_T("DFC_PGDN_TO")}, + {SPINORPROGRAMFAIL,_T("SPINORPROGRAMFAIL")}, + {SPINORERASEFAIL,_T("SPINORERASEFAIL")}, + {InvalidOEMVerifyKeyError,_T("InvalidOEMVerifyKeyError")}, + {InvalidOBMImageError,_T("InvalidOBMImageError")}, + {SecureBootFailureError,_T("SecureBootFailureError ")}, + {InvalidSecureBootMethodError,_T("InvalidSecureBootMethodError")}, + {UnsupportedFlashError,_T("UnsupportedFlashError")}, + {InvalidCaddoFIFOEntryError,_T("InvalidCaddoFIFOEntryError ")}, + {InvalidCaddoKeyNumberError,_T("InvalidCaddoKeyNumberError ")}, + {InvalidCaddoKeyTypeError,_T("InvalidCaddoKeyTypeError")}, + {RSADigitalSignatureDecryptError,_T("RSADigitalSignatureDecryptError")}, + {InvalidHashValueLengthError,_T("InvalidHashValueLengthError ")}, + {InvalidTIMImageError,_T("InvalidTIMImageError")}, + {HashSizeMismatch,_T("HashSizeMismatch")}, + {InvalidKeyHashError,_T("InvalidKeyHashError")}, + {TIMNotFound,_T("TIMNotFound")}, + {WTMStateError,_T("WTMStateError")}, + {FuseRWError,_T("FuseRWError")}, + {InvalidOTPHashError,_T("InvalidOTPHashError, keypair in current blf configuration is not the key of fuse")}, + {CRCFailedError,_T("CRCFailedError ")}, + {SaveStateNotFound,_T("SaveStateNotFound")}, + {WTMInitializationError,_T("WTMInitializationError")}, + {ImageNotFound,_T("ImageNotFound")}, + {InvalidImageHash,_T("InvalidImageHash")}, + {MicroCodePatchingError,_T("MicroCodePatchingError")}, + {SetJtagKeyError,_T("SetJtagKeyError")}, + {WTMDisabled,_T("WTMDisabled")}, + {PlatformVerifyFailure,_T("PlatformVerifyFailure")}, + {ImageLoadError,_T("ImageLoadError ")}, + {IPPCPHASHERROR,_T("IPPCPHASHERROR ")}, + {DownloadPortError,_T("DownloadPortError")}, + {DownloadError,_T("DownloadError")}, + {FlashNotErasedError,_T("FlashNotErasedError")}, + {InvalidKeyLengthError,_T("InvalidKeyLengthError")}, + {DownloadImageTooBigError,_T("DownloadImageTooBigError")}, + {UsbPreambleError,_T("UsbPreambleError")}, + {TimeOutError,_T("TimeOutError")}, + {UartReadWriteTimeOutError,_T("UartReadWriteTimeOutError")}, + {UnknownImageError,_T("UnknownImageError")}, + {MessageBufferFullError,_T("MessageBufferFullError")}, + {NoEnumerationResponseTimeOutError,_T("NoEnumerationResponseTimeOutError")}, + {UnknownProtocolCmd,_T("UnknownProtocolCmd")}, + {UsbRxError,_T("UsbRxError")}, + {ForceDownloadPseudoError,_T("ForceDownloadPseudoError")}, + {UsbTxError,_T("UsbTxError")}, + {JtagReEnableError,_T("JtagReEnableError")} , + {JtagReEnableOEMPubKeyError,_T("JtagReEnableOEMPubKeyError")}, + {JtagReEnableOEMSignedPassWdError,_T("JtagReEnableOEMSignedPassWdError")}, + {JtagReEnableTimeOutError,_T("JtagReEnableTimeOutError")}, + {JtagReEnableOEMKeyLengthError,_T("JtagReEnableOEMKeyLengthError ")} , + {SDMMC_SWITCH_ERROR,_T("SDMMC_SWITCH_ERROR")}, + {SDMMC_ERASE_RESET_ERROR,_T("SDMMC_ERASE_RESET_ERROR")}, + {SDMMC_CIDCSD_OVERWRITE_ERROR,_T("SDMMC_CIDCSD_OVERWRITE_ERROR")}, + {SDMMC_OVERRUN_ERROR,_T("SDMMC_OVERRUN_ERROR ")}, + {SDMMC_UNDERUN_ERROR,_T("SDMMC_UNDERUN_ERROR ")}, + {SDMMC_GENERAL_ERROR,_T("SDMMC_GENERAL_ERROR ")}, + {SDMMC_CC_ERROR,_T("SDMMC_CC_ERROR")}, + {SDMMC_ECC_ERROR,_T("SDMMC_ECC_ERROR")}, + {SDMMC_ILL_CMD_ERROR,_T("SDMMC_ILL_CMD_ERROR")}, + {SDMMC_COM_CRC_ERROR,_T("SDMMC_COM_CRC_ERROR")}, + {SDMMC_LOCK_ULOCK_ERRROR,_T("SDMMC_LOCK_ULOCK_ERRROR")}, + {SDMMC_LOCK_ERROR,_T("SDMMC_LOCK_ERROR ")}, + {SDMMC_WP_ERROR,_T("SDMMC_WP_ERROR")}, + {SDMMC_ERASE_PARAM_ERROR,_T("SDMMC_ERASE_PARAM_ERROR")}, + {SDMMC_ERASE_SEQ_ERROR,_T("SDMMC_ERASE_SEQ_ERROR")}, + {SDMMC_BLK_LEN_ERROR,_T("SDMMC_BLK_LEN_ERROR")}, + {SDMMC_ADDR_MISALIGN_ERROR,_T("SDMMC_ADDR_MISALIGN_ERROR")}, + {SDMMC_ADDR_RANGE_ERROR,_T("SDMMC_ADDR_RANGE_ERROR")}, + {SDMMCDeviceNotReadyError,_T("SDMMCDeviceNotReadyError")}, + {SDMMCInitializationError,_T("SDMMCInitializationError")}, + {SDMMCDeviceVoltageNotSupported,_T("SDMMCDeviceVoltageNotSupported")}, + {SDMMCWriteError,_T("SDMMCWriteError")}, + {SDMMCAltBootDataAlignmentError,_T("SDMMCAltBootDataAlignmentError")}, + {SDMMC_SGPT_ILLEGAL_LENGTH,_T("SDMMC_SGPT_ILLEGAL_LENGTH")}, + {SDIOReadError,_T("SDIOReadError")}, + {SDIOWriteError,_T("SDIOWriteError")}, + {SDIOOutOfSyncError,_T("SDIOOutOfSyncError")}, + {SDIONullBuffer,_T("SDIONullBuffer")}, + {SDIOBufferMisalignError,_T("SDIOBufferMisalignError")}, + {SDIOImageSizeError,_T("SDIOImageSizeError")}, + {FUSE_FuseBlockNotActive,_T("FUSE_FuseBlockNotActive")}, + {FUSE_BufferTooSmall,_T("FUSE_BufferTooSmall")}, + {FUSE_FuseBlockLocked,_T("FUSE_FuseBlockLocked ")}, + {FUSE_UnsupportedFuseBlock,_T("FUSE_UnsupportedFuseBlock")}, + {FUSE_IncompleteBurnRequest,_T("FUSE_IncompleteBurnRequest")}, + {FUSE_NoBurnRequest,_T("FUSE_NoBurnRequest")}, + {FUSE_FuseBlockFieldNotActive,_T("FUSE_FuseBlockFieldNotActive")}, + {FUSE_BurnError,_T("FUSE_BurnError")}, + {FUSE_FuseBlockFieldOverflow,_T("FUSE_FuseBlockFieldOverflow")}, + {FUSE_InvalidFuseBlockField,_T("FUSE_InvalidFuseBlockField")}, + {FUSE_FuseBlockCompareFailed,_T("FUSE_FuseBlockCompareFailed")}, + {FUSE_InvalidState,_T("FUSE_InvalidState")}, + {FUSE_InvalidBufferSize,_T("FUSE_InvalidBufferSize")}, + {FUSE_BitSetError,_T("FUSE_BitSetError")}, + {FUSE_FuseBlockLockedAndNotReadable,_T("FUSE_FuseBlockLockedAndNotReadable")}, + {FUSE_FuseBlockFieldFull,_T("FUSE_FuseBlockFieldFull")}, + {FUSE_FuseSoftwareResetTimeout,_T("FUSE_FuseSoftwareResetTimeout")}, + {FUSE_FuseBurnTimeout,_T("FUSE_FuseBurnTimeout")}, + {FUSE_FuseBlockStickyBitSet,_T("FUSE_FuseBlockStickyBitSet")}, + {FUSE_UsbPhyBandgapNotEnabled,_T("FUSE_UsbPhyBandgapNotEnabled")}, + {FUSE_UncorrectableEccError,_T("FUSE_UncorrectableEccError")}, + {FUSE_FieldWriteProtectedByEcc,_T("FUSE_FieldWriteProtectedByEcc")}, + {FUSE_LastLogicalBitBurned,_T("FUSE_LastLogicalBitBurned")}, + {FUSE_TamperError,_T("FUSE_TamperError")}, + {FUSE_FuseReprogrammingError,_T("FUSE_FuseReprogrammingError")}, + {FUSE_IncompleteFuseFieldsSetup,_T("FUSE_IncompleteFuseFieldsSetup")}, + {GEU_FuseBlockNotActive,_T("GEU_FuseBlockNotActive")}, + {GEU_BufferTooSmall,_T("GEU_BufferTooSmall")}, + {GEU_FuseBlockLocked,_T("GEU_FuseBlockLocked")}, + {GEU_UnsupportedFuseBlock,_T("GEU_UnsupportedFuseBlock ")}, + {GEU_IncompleteBurnRequest,_T("GEU_IncompleteBurnRequest ")}, + {GEU_NoBurnRequest,_T("GEU_NoBurnRequest")}, + {GEU_FuseBlockFieldNotActive,_T("GEU_FuseBlockFieldNotActive")}, + {GEU_BurnError,_T("GEU_BurnError")}, + {GEU_FuseBlockFieldOverflow,_T("GEU_FuseBlockFieldOverflow")}, + {GEU_InvalidFuseBlockField,_T("GEU_InvalidFuseBlockField")}, + {GEU_FuseBlockCompareFailed,_T("GEU_FuseBlockCompareFailed")}, + {GEU_InvalidState,_T("GEU_InvalidState")}, + {GEU_InvalidBufferSize,_T("GEU_InvalidBufferSize")}, + {GEU_BitSetError,_T("GEU_BitSetError")}, + {GEU_FuseBlockLockedAndNotReadable,_T("GEU_FuseBlockLockedAndNotReadable")}, + {GEU_FuseBlockFieldFull,_T("GEU_FuseBlockFieldFull")}, + {GEU_FuseSoftwareResetTimeout,_T("GEU_FuseSoftwareResetTimeout")}, + {GEU_FuseBurnTimeout,_T("GEU_FuseBurnTimeout")}, + {GEU_FuseBlockStickyBitSet,_T("GEU_FuseBlockStickyBitSet")}, + {GEU_UsbPhyBandgapNotEnabled,_T("GEU_UsbPhyBandgapNotEnabled")}, + {GEU_UncorrectableEccError,_T("GEU_UncorrectableEccError")}, + {GEU_FieldWriteProtectedByEcc,_T("GEU_FieldWriteProtectedByEcc")}, + {GEU_LastLogicalBitBurned,_T("GEU_LastLogicalBitBurned")}, + {GEU_TamperError,_T("GEU_TamperError")}, + {GEU_FuseReprogrammingError,_T("GEU_FuseReprogrammingError")}, + {GEU_IncompleteFuseFieldsSetup,_T("GEU_IncompleteFuseFieldsSetup")}, + {TZ_Region0NotProtected,_T("TZ_Region0NotProtected")}, + {TZ_FusesNotConfiguredForTrustzone,_T("TZ_FusesNotConfiguredForTrustzone")}, + {TZ_PackageNotFound ,_T("TZ_PackageNotFound")}, + {TZ_InitDisabled ,_T("TZ_InitDisabled")}, + {TZ_UnknownOperation ,_T("TZ_UnknownOperation")}, + {DDR_Package_Obsolete,_T("DDR_Package_Obsolete")}, + {DDR_Unknown_Operation,_T("DDR_Unknown_Operation")}, + {DDR_MemoryTest_Failed,_T("DDR_MemoryTest_Failed")}, + {DDR_InitDisabled,_T("DDR_InitDisabled")}, + {DDR_CMCC_Package_Obsolete,_T("DDR_CMCC_Package_Obsolete")}, + {DDR_Trustzone_Package_Obsolete,_T("DDR_Trustzone_Package_Obsolete")}, + {DDR_PackageNotFound,_T("DDR_PackageNotFound")}, + {DDR_FusesNotConfiguredForTrustzone,_T("DDR_FusesNotConfiguredForTrustzone")}, + {UnknownInstruction,_T("UnknownInstruction ")}, + {InstructionTimeout,_T("InstructionTimeout")}, + {INSTR_InvalidAddress,_T("INSTR_InvalidAddress")}, + {INSTR_InvalidScratchMemoryId,_T("INSTR_InvalidScratchMemoryId")}, + {INSTR_InvalidMaskOrValue,_T("INSTR_InvalidMaskOrValue")}, + {Sparse_ImageLengthLimitExceeded,_T("Sparse_ImageLengthLimitExceeded")}, + {Sparse_BadMagic,_T("Sparse_BadMagic")}, + {Sparse_IncompatibleFormat,_T("Sparse_IncompatibleFormat")}, + {Sparse_BadChunkSize,_T("Sparse_BadChunkSize")}, + {Sparse_BogusDontCareChunk,_T("Sparse_BogusDontCareChunk")}, + {Sparse_UnknownChunkId,_T("Sparse_UnknownChunkId")}, + {Sparse_WriteError,_T("Sparse_WriteError")}, + {SDH_CMD_TIMEOUT_ERR,_T("SDH_CMD_TIMEOUT_ERR")}, + {SDH_CMD_CRC_ERR,_T("SDH_CMD_CRC_ERR")}, + {SDH_CMD_END_BIT_ERR,_T("SDH_CMD_END_BIT_ERR")}, + {SDH_CMD_INDEX_ERR,_T("SDH_CMD_INDEX_ERR")}, + {SDH_DATA_TIMEOUT_ERR,_T("SDH_DATA_TIMEOUT_ERR")}, + {SDH_RD_DATA_CRC_ERR,_T("SDH_RD_DATA_CRC_ERR")}, + {SDH_RD_DATA_END_BIT_ERR,_T("SDH_RD_DATA_END_BIT_ERR")}, + {SDH_AUTO_CMD12_ERR ,_T("SDH_AUTO_CMD12_ERR")}, + {SDH_ADMA_ERR,_T("SDH_ADMA_ERR")}, + {SDH_TUNE_ERR,_T("SDH_TUNE_ERR")}, + {SDH_SPI_ERR,_T("SDH_SPI_ERR")}, + {SDH_AXI_RESP_ERR,_T("SDH_AXI_RESP_ERR")}, + {SDH_CPL_TIMEOUT_ERR,_T("SDH_CPL_TIMEOUT_ERR")}, + {SDH_CRC_STATUS_ERR,_T("SDH_CRC_STATUS_ERR")}, + {IMAP_PackageNotFound,_T("IMAP_PackageNotFound")}, + {IMAP_ErrorFormat,_T("IMAP_ErrorFormat")}, + {IMAP_DTIMNotFound,_T("IMAP_DTIMNotFound")}, + {IMAP_DTIMLoadError,_T("IMAP_DTIMLoadError")}, + {IMAP_DTIMValidationFailed,_T("IMAP_DTIMValidationFailed")}, + {IMAP_BootFailed,_T("IMAP_BootFailed")}, + {IMAP_KeyNotFound,_T("IMAP_KeyNotFound")}, + {IMAP_ImageLoadError,_T("IMAP_ImageLoadError")}, + {IMAP_ImageValidateError,_T("IMAP_ImageValidateError")}, + {MRD_BadMagic,_T("MRD_BadMagic")}, + {MRD_CheckSumNotMatch,_T("MRD_CheckSumNotMatch")}, + {MRD_IMEINotMatch,_T("MRD_IMEINotMatch")}, + +}; + + +static NOTIFICATIONTABLE WTPTPNotificationMsg[MAXNOTIFICATIONSCODES] = +{ + {PlatformBusy,_T("Platform is busy")}, + {PlatformReady,_T("Platform is Ready")}, + {PlatformResetBBT,_T("Reset BBT")}, + {PlatformEraseAllFlash,_T("Erase All flash begin")}, + {PlatformDisconnect,_T("platform is disconnect")}, + {PlatformEraseAllFlashDone,_T("Erase All flash done")}, + {PlatformEraseAllFlashWithoutBurn,_T("Erase All flash without burning begin")}, + {PlatformEraseAllFlashWithoutBurnDone,_T("Erase All flash without burning Done")}, + {PlatformFuseOperationStart,_T("Platform Fuse Operation Start")}, + {PlatformFuseOperationDone,_T("Platform Fuse Operation Done")}, + {PlatformUEInfoStart,_T("Platform UE Info Operation Start")}, + {PlatformUEInfoDone,_T("Platform UE Info Operation Done")} +}; +#else +static ERRORCODETABLE WTPTPErrorCodes[MAXERRORCODES]= +{ + {NoError}, + {NotFoundError}, + {GeneralError}, + {WriteError}, + {ReadError} , + {NotSupportedError} , + {InvalidPlatformConfigError}, + {InvalidPlatformState}, + {InvalidSizeError}, + {ProbeListExhaustError}, + {DDR_NotInitializedError}, + {UnknownReservedPackage}, + {NULLPointer}, + {NANDIDDISMATCH }, + {FBF_VersionNotMatch}, + {FBF_DeviceMoreThanOne}, + {PlatformConfigBuckError}, + {ChipIdMismatch}, + {EraseError}, + {ProgramError}, + {InvalidBootTypeError}, + {ProtectionRegProgramError}, + {NoOTPFound}, + {BBTReadError}, + {MDOCInitFailed}, + {OneNandInitFailed}, + {MDOCFormatFailed}, + {BBTExhaustedError}, + {NANDNotFound}, + {SDMMCNotFound}, + {FlexOneNANDNotFound}, + {SDMMCReadError}, + {XIPReadError}, + {FlexOneNANDError}, + {FlashDriverInitError}, + {FlashFuncNotDefined}, + {OTPError}, + {InvalidAddressRangeError}, + {FlashLockError}, + {ReadDisturbError}, + {FlashReadError}, + {SPIFlashNotResponding}, + {ImageOverlayError}, + {FlashAddrNotChunkAlign }, + {FlashAddrNotWordAlign }, + {BBTOUTOFRANGE }, + {FlashWriteVerifyError }, + {FlashAddrOutOfRange }, + {DFCDoubleBitError}, + {DFCSingleBitError}, + {DFCCS0BadBlockDetected}, + {DFCCS1BadBlockDetected}, + {DFCInitFailed}, + {DFCONFIConfigError}, + {DFC_WRREQ_TO}, + {DFC_WRCMD_TO}, + {DFC_RDDREQ_TO} , + {DFC_RDY_TO}, + {DFCCS0CommandDoneError}, + {DFCCS1CommandDoneError}, + {DFC_PGDN_TO}, + {SPINORPROGRAMFAIL}, + {SPINORERASEFAIL}, + {InvalidOEMVerifyKeyError}, + {InvalidOBMImageError}, + {SecureBootFailureError}, + {InvalidSecureBootMethodError}, + {UnsupportedFlashError}, + {InvalidCaddoFIFOEntryError}, + {InvalidCaddoKeyNumberError}, + {InvalidCaddoKeyTypeError}, + {RSADigitalSignatureDecryptError}, + {InvalidHashValueLengthError}, + {InvalidTIMImageError}, + {HashSizeMismatch}, + {InvalidKeyHashError}, + {TIMNotFound}, + {WTMStateError}, + {FuseRWError}, + {InvalidOTPHashError}, + {CRCFailedError}, + {SaveStateNotFound}, + {WTMInitializationError}, + {ImageNotFound}, + {InvalidImageHash}, + {MicroCodePatchingError}, + {SetJtagKeyError}, + {WTMDisabled}, + {PlatformVerifyFailure}, + {ImageLoadError}, + {IPPCPHASHERROR}, + {DownloadPortError}, + {DownloadError}, + {FlashNotErasedError}, + {InvalidKeyLengthError}, + {DownloadImageTooBigError}, + {UsbPreambleError}, + {TimeOutError}, + {UartReadWriteTimeOutError}, + {UnknownImageError}, + {MessageBufferFullError}, + {NoEnumerationResponseTimeOutError}, + {UnknownProtocolCmd}, + {UsbRxError}, + {ForceDownloadPseudoError}, + {UsbTxError}, + {JtagReEnableError} , + {JtagReEnableOEMPubKeyError}, + {JtagReEnableOEMSignedPassWdError}, + {JtagReEnableTimeOutError}, + {JtagReEnableOEMKeyLengthError} , + {SDMMC_SWITCH_ERROR}, + {SDMMC_ERASE_RESET_ERROR}, + {SDMMC_CIDCSD_OVERWRITE_ERROR}, + {SDMMC_OVERRUN_ERROR}, + {SDMMC_UNDERUN_ERROR}, + {SDMMC_GENERAL_ERROR}, + {SDMMC_CC_ERROR}, + {SDMMC_ECC_ERROR}, + {SDMMC_ILL_CMD_ERROR}, + {SDMMC_COM_CRC_ERROR}, + {SDMMC_LOCK_ULOCK_ERRROR}, + {SDMMC_LOCK_ERROR}, + {SDMMC_WP_ERROR}, + {SDMMC_ERASE_PARAM_ERROR}, + {SDMMC_ERASE_SEQ_ERROR}, + {SDMMC_BLK_LEN_ERROR}, + {SDMMC_ADDR_MISALIGN_ERROR}, + {SDMMC_ADDR_RANGE_ERROR}, + {SDMMCDeviceNotReadyError}, + {SDMMCInitializationError}, + {SDMMCDeviceVoltageNotSupported}, + {SDMMCWriteError}, + {SDMMCAltBootDataAlignmentError}, + {SDMMC_SGPT_ILLEGAL_LENGTH}, + {SDIOReadError}, + {SDIOWriteError}, + {SDIOOutOfSyncError}, + {SDIONullBuffer}, + {SDIOBufferMisalignError}, + {SDIOImageSizeError}, + {FUSE_FuseBlockNotActive}, + {FUSE_BufferTooSmall}, + {FUSE_FuseBlockLocked}, + {FUSE_UnsupportedFuseBlock}, + {FUSE_IncompleteBurnRequest}, + {FUSE_NoBurnRequest}, + {FUSE_FuseBlockFieldNotActive}, + {FUSE_BurnError}, + {FUSE_FuseBlockFieldOverflow}, + {FUSE_InvalidFuseBlockField}, + {FUSE_FuseBlockCompareFailed}, + {FUSE_InvalidState}, + {FUSE_InvalidBufferSize}, + {FUSE_BitSetError}, + {FUSE_FuseBlockLockedAndNotReadable}, + {FUSE_FuseBlockFieldFull}, + {FUSE_FuseSoftwareResetTimeout}, + {FUSE_FuseBurnTimeout}, + {FUSE_FuseBlockStickyBitSet}, + {FUSE_UsbPhyBandgapNotEnabled}, + {FUSE_UncorrectableEccError}, + {FUSE_FieldWriteProtectedByEcc}, + {FUSE_LastLogicalBitBurned}, + {FUSE_TamperError}, + {FUSE_FuseReprogrammingError}, + {FUSE_IncompleteFuseFieldsSetup}, + {GEU_FuseBlockNotActive}, + {GEU_BufferTooSmall}, + {GEU_FuseBlockLocked}, + {GEU_UnsupportedFuseBlock}, + {GEU_IncompleteBurnRequest}, + {GEU_NoBurnRequest}, + {GEU_FuseBlockFieldNotActive}, + {GEU_BurnError}, + {GEU_FuseBlockFieldOverflow}, + {GEU_InvalidFuseBlockField}, + {GEU_FuseBlockCompareFailed}, + {GEU_InvalidState}, + {GEU_InvalidBufferSize}, + {GEU_BitSetError}, + {GEU_FuseBlockLockedAndNotReadable}, + {GEU_FuseBlockFieldFull}, + {GEU_FuseSoftwareResetTimeout}, + {GEU_FuseBurnTimeout}, + {GEU_FuseBlockStickyBitSet}, + {GEU_UsbPhyBandgapNotEnabled}, + {GEU_UncorrectableEccError}, + {GEU_FieldWriteProtectedByEcc}, + {GEU_LastLogicalBitBurned}, + {GEU_TamperError}, + {GEU_FuseReprogrammingError}, + {GEU_IncompleteFuseFieldsSetup}, + {TZ_Region0NotProtected}, + {TZ_FusesNotConfiguredForTrustzone}, + {TZ_PackageNotFound }, + {TZ_InitDisabled }, + {TZ_UnknownOperation }, + {DDR_Package_Obsolete}, + {DDR_Unknown_Operation}, + {DDR_MemoryTest_Failed}, + {DDR_InitDisabled}, + {DDR_CMCC_Package_Obsolete}, + {DDR_Trustzone_Package_Obsolete}, + {DDR_PackageNotFound}, + {DDR_FusesNotConfiguredForTrustzone}, + {UnknownInstruction}, + {InstructionTimeout}, + {INSTR_InvalidAddress}, + {INSTR_InvalidScratchMemoryId}, + {INSTR_InvalidMaskOrValue}, + {Sparse_ImageLengthLimitExceeded}, + {Sparse_BadMagic}, + {Sparse_IncompatibleFormat}, + {Sparse_BadChunkSize}, + {Sparse_BogusDontCareChunk}, + {Sparse_UnknownChunkId}, + {Sparse_WriteError}, + {SDH_CMD_TIMEOUT_ERR}, + {SDH_CMD_CRC_ERR}, + {SDH_CMD_END_BIT_ERR}, + {SDH_CMD_INDEX_ERR}, + {SDH_DATA_TIMEOUT_ERR}, + {SDH_RD_DATA_CRC_ERR}, + {SDH_RD_DATA_END_BIT_ERR}, + {SDH_AUTO_CMD12_ERR }, + {SDH_ADMA_ERR}, + {SDH_TUNE_ERR}, + {SDH_SPI_ERR}, + {SDH_AXI_RESP_ERR}, + {SDH_CPL_TIMEOUT_ERR}, + {SDH_CRC_STATUS_ERR}, + {IMAP_PackageNotFound}, + {IMAP_ErrorFormat}, + {IMAP_DTIMNotFound}, + {IMAP_DTIMLoadError}, + {IMAP_DTIMValidationFailed}, + {IMAP_BootFailed}, + {IMAP_KeyNotFound}, + {IMAP_ImageLoadError}, + {IMAP_ImageValidateError}, + {MRD_BadMagic}, + {MRD_CheckSumNotMatch}, + {MRD_IMEINotMatch} + +}; + + +static NOTIFICATIONTABLE WTPTPNotificationMsg[MAXNOTIFICATIONSCODES] = +{ + {PlatformBusy}, + {PlatformReady}, + {PlatformResetBBT}, + {PlatformEraseAllFlash}, + {PlatformDisconnect}, + {PlatformEraseAllFlashDone}, + {PlatformEraseAllFlashWithoutBurn}, + {PlatformEraseAllFlashWithoutBurnDone}, + {PlatformFuseOperationStart}, + {PlatformFuseOperationDone}, + {PlatformUEInfoStart}, + {PlatformUEInfoDone} +}; + +#endif + +void Copy_NotifyStatus(PProcInfo me,struct _NotifyStatus* rhs); +void New_DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC(pDDR_FLASH_DOWNLOADIMAGE_INFO_SPEC me); +void Del_DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC(pDDR_FLASH_DOWNLOADIMAGE_INFO_SPEC me); +void Copy_DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC(pDDR_FLASH_DOWNLOADIMAGE_INFO_SPEC me,struct _DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC* DDRFlashDownloadImageInfo); +void Copy_WTPTPREAMBLECOMMAND(pWTPTPREAMBLECOMMAND me,struct _WTPTPREAMBLECOMMAND* WTPCMD); +void DelInstanceParams(PInstanceParams me); +void NewInstanceParams(PInstanceParams me); + +#endif diff --git a/fbfdownloader/src/ReadMe.txt b/fbfdownloader/src/ReadMe.txt new file mode 100644 index 00000000..70e7cab4 --- /dev/null +++ b/fbfdownloader/src/ReadMe.txt @@ -0,0 +1,9 @@ +FBFDownloader_makefile is the Makefile of fbfdownloader +libmakefile is the Makefile of libfbfdown.a, api is in fbfdownload.h. + + +//return 0 SUCCRSS +//return 1 FAIL +//timeout 0 Infinite Wait +//timeout >0 Wait N seconds for Download +int fbfdownload(char * strBinFilePath, int timeout); \ No newline at end of file diff --git a/fbfdownloader/src/Tim.h b/fbfdownloader/src/Tim.h new file mode 100644 index 00000000..30e1ef6f --- /dev/null +++ b/fbfdownloader/src/Tim.h @@ -0,0 +1,960 @@ +#ifndef __TIM_H__ +#define __TIM_H__ + +//#include "general.h" +#include "Macrodef.h" +#include "TimIncludedType.h" +/******************* TIM Layout ************************************/ +/* Below Presents the Maxiumum Size TIM layout in memory + +VERSION_I VersionBind; // 0 +FLASH_I FlashInfo; // 0x10 +UINT_T NumImages; // 0x20 +UINT_T NumKeys; // 0x24 +UINT_T SizeOfReserved; // 0x28 +IMAGE_INFO IMG[MAX_IMAGES]; // 0x2C +KEY_MOD Key[MAX_KEYS]; // 0x284 +UINT_T Reserved[0x4E8]; // 0x908 (0x4E8 bytes) +PLAT_DS TBTIM_DS; // 0xDF0 + // 0x1000 = 4 KB +Below Presents the Maxiumum Size NTIM layout in memory + +VERSION_I VersionBind; // 0 +FLASH_I FlashInfo; // 0x10 +UINT_T NumImages; // 0x20 +UINT_T NumKeys; // 0x24 +UINT_T SizeOfReserved; // 0x28 +IMAGE_INFO IMG[MAX_IMAGES]; // 0x2C +UINT_T Reserved[0xD80]; // 0x284 +NTIM, *pNTIM; // 0x1000 = 4KB +/******************* TIM Layout ************************************/ + + +// TIM Versions +#define TIM_3_1_01 0x30101 +#define TIM_3_2_00 0x30200 // Support for Partitioning +#define TIM_3_3_00 0x30300 // Support for ECDSA-256 and 64 bit addressing +#define TIM_3_4_00 0x30400 // Support for ECDSA-521 +#define TIM_3_5_00 0x30500 // Support for Encrypted Boot + +const int MAX_HASH = 256; +const int MAX_HASH_IN_BITS = 512; // 512 bits + +// B1 TIM +#include "Typedef.h" +#define MAX_IMAGES 100 +#define MAX_KEYS 3 +#define MAX_TIM_SIZE 0x1000 +#define TIMBUFFER 4096 //4k for a Tim structure size +#define MAXKEYSIZEWORDS 64 // 2048 bits +#define MAXRSAKEYSIZEWORDS 64 // 2048 bits +#define MAXECCKEYSIZEWORDS 17 // 521 bits+ + +// Predefined Image Identifiers +#define TIMIDENTIFIER 0x54494D48 // "TIMH" +#define TIM1IDENTIFIER 0x54494D31 // "TIM1" +#define TIM4IDENTIFIER 0x54494D34 // "TIM4" +#define WTMIDENTIFIER 0x57544D49 // "WTMI" +#define OBMIDENTIFIER 0x4F424D49 // "OBMI" +#define MONITORIDENTIFIER 0x4D4F4E49 // "MONI" +#define TZSWIDENTIFIER 0x545A5349 // "TZSI" This is also used as consumer ID +#define TBRIDENTIFIER 0x54425249 // "TBRI" This is also used as consumer ID +#define DKBIDENTIFIER 0x444B4249 // "DKBI" +#define JTAGIDENTIFIER 0x4A544147 // "JTAG" +#define AUTHIDENTIFIER 0x41555448 // "AUTH" +#define PATCHIDENTIFIER 0x50415443 // "PATC" +#define TCAIDENTIFIER 0x5443414B // "TCAK" +#define OSLOADERID 0x4F534C4F // "OSLO" +#define ROMC 0x524F4D43 // "ROMC" +#define DSIGIDENTIFIER 0x44534947 // "DSIG" +#define ENCKIDENTIFIER 0x454E434B // "ENCK" + +// WTP Format Recognized Reserved Area Indicator +#define WTPRESERVEDAREAID 0x4F505448 // "OPTH" + +// Reserved Area Package Headers +#define AUTOBIND 0x42494E44 // "BIND" +#define TERMINATORID 0x5465726D // "Term" +#define GPIOID 0x4750494F // "GPIO" +#define UARTID 0x55415254 // "UART" +#define USBID 0x00555342 // "USB" +#define RESUMEID 0x5265736D // "Resm" +#define USBVENDORREQ 0x56524551 // "VREQ" +#define TBR_XFER 0x54425258 // "TBRX" +#define RESUMEBLID 0x52736D32 // "Rsm2" +#define ESCAPESEQID 0x45534353 // "ESCS" +#define ESCSEQID_v2 0x45537632 // "ESv2" Escape Sequence Version 2 +#define OEMCUSTOMID 0x43555354 // "CUST" +#define NOMONITORID 0x4E4F4D43 // "NOMC" +#define COREID 0x434F5245 // "CORE" +#define BBMTID 0x42424D54 // "BBMT" +#define QNXBOOT 0x514E5850 // "QNXP" +#define GPP1ID 0x47505031 // "GPP1" Processed in RESERVEDAREA_State +#define GPP2ID 0x47505032 // "GPP2" Processed in XFER_State +#define ROMRESUMEID 0x52736D33 // "Rsm3" +#define PINID 0x50494E50 // "PINP" +#define IMAPID 0x494D4150 // "IMAP" + + +// DDR Related ID's +#define DDRID 0x44447248 // "DDrH" +#define DDRGID 0x44445247 // "DDRG" +#define DDRTID 0x44445254 // "DDRT" +#define DDRCID 0x44445243 // "DDRC" +#define CMCCID 0x434d4343 // "CMCC" + +// trust zone package +#define CIDPID 0x43494450 // "CIDP" +#define TZRI 0x545A5249 // ”TZRI?#endif + +// Operating mode related ID's +#define FREQID 0x46524551 // "FREQ" +#define VOLTID 0x564f4c54 // "VOLT" +#define OPMODEID 0x4d4f4445 // "MODE" +#define OPDIVID 0x4f504456 // "OPDV" +#define CLKEID 0x434c4b45 // "CLKE" + +// trust zone package +#define TZID 0x545A4944 // "TZID" +#define TZON 0x545A4f4E // "TZON" Register based + +#define FUNC 0x46554E43 // "FUNC" +#define PROI 0x50524F49 // "PROI" + +#define ERASID 0x45524153 //ERAS +#define SKIPID 0x534B4950 //SKIP +// USB +#define DESCRIPTOR_RES_ID 0x55534200 // "USB" +#define NUM_USB_DESCRIPTORS 10 +#define MAX_USB_STRINGS 7 + +#define NOFREQUENCYID 0x4E4F4643 // "NOFC" +#define NOKEYDETECTID 0x4E4F4B44 // "NOKD" + +#define TRFU 0x54524655 //TR069 control info. +#define DTYP 0x44545950 //DDR type +#define LTWS 0x4C545753 //LTG LWG SELECT PACKAGE +#define OTAI 0x4F544149 //FOTA Info +#define DDR_FLASH_MCP_MAP_PACKAGE_ID 0X44464D50 // "DFMP" +#define CITA_CUMIZED_INFO_TRANSFER_TOAP_ID 0X43495441 // "CITA" +#define BBMTYPEID 0x42424D54 // "BBMT" +#define FLASH_GEO_PKG_ID 0x46475049 // "FGPI" Flash Geometry Package ID +#define BBCS 0x42424353 //Bad block report switch +#define CRCS 0x43524353 //CRC switch + + +/*************************************************************************** +* +* New package for DDR auto adjust -- start +* +****************************************************************************/ + +#define DDRBYTESELECT 0x44444253 // "DDBS", ddr byte select +#define DDR_SAMSUNG_ID 0x49443031 // "ID01" +#define DDR_QIMONDA_ID 0x49443032 // "ID02" +#define DDR_ELPIDA_ID 0x49443033 // "ID03" +#define DDR_ETRON_ID 0x49443034 // "ID04" +#define DDR_NANYA_ID 0x49443035 // "ID05" +#define DDR_HYNIX_ID 0x49443036 // "ID06" +#define DDR_MOSEL_ID 0x49443037 // "ID07" +#define DDR_WINBOND_ID 0x49443038 // "ID08" +#define DDR_ESMT_ID 0x49443039 // "ID09" +#define DDR_RESERVED_ID 0x49443041 // "ID0A" +#define DDR_SPANSION_ID 0x49443042 // "ID0B" +#define DDR_SST_ID 0x49443043 // "ID0C" +#define DDR_ZMOS_ID 0x49443044 // "ID0D" +#define DDR_INTEL_ID 0x49443045 // "ID0E" +#define DDR_NUMONYX_ID 0x49443046 // "ID0F" +#define DDR_MICRON_ID 0x49443130 // "ID10" +#define DDR_TOSHIBA_ID 0x49443131 // "ID11" + + +typedef enum +{ + eUSB_DEVICE_DESCRIPTOR = (DESCRIPTOR_RES_ID | 0), + eUSB_CONFIG_DESCRIPTOR = (DESCRIPTOR_RES_ID | 1), + eUSB_INTERFACE_DESCRIPTOR = (DESCRIPTOR_RES_ID | 2), + eUSB_LANGUAGE_STRING_DESCRIPTOR = (DESCRIPTOR_RES_ID | 3), + eUSB_MANUFACTURER_STRING_DESCRIPTOR = (DESCRIPTOR_RES_ID | 4), + eUSB_PRODUCT_STRING_DESCRIPTOR = (DESCRIPTOR_RES_ID | 5), + eUSB_SERIAL_STRING_DESCRIPTOR = (DESCRIPTOR_RES_ID | 6), + eUSB_INTERFACE_STRING_DESCRIPTOR = (DESCRIPTOR_RES_ID | 7), + eUSB_DEFAULT_STRING_DESCRIPTOR = (DESCRIPTOR_RES_ID | 8), + eUSB_ENDPOINT_DESCRIPTOR = (DESCRIPTOR_RES_ID | 9) +} USB_DESCRIPTORS; + +typedef enum +{ + COREID_MP1 = 0, + COREID_MP2 = 1, + COREID_MM = 2 +} +COREID_T; + +typedef enum +{ + BBMT_TYPE_NO_BBM = 0, + BBMT_TYPE_LEGACY = 1, + BBMT_TYPE_MARVELL_FM_V1 = 2, + BBMT_TYPE_MARVELL_FM_V2 = 3 +} +BBMT_TYPE_T; +// Global Identifiers +#define FFIDENTIFIER 0x00004646 // "FF" +#define ALTIDENTIFIER 0x00414C54 // "ALT" +#define DIFFIDENTIFIER 0x44696666 // "Diff" +#define SEIDENTIFIER 0x00005345 // "SE" +#define U2DIDENTIFIER 0x55534232 // "USB2" +#define PINSIDENTIFIER 0x50696E73 // "Pins" +#define MDOCFORMATID 0x6d444f43 // "mDOC" +#define MDOCBINID 0x6d42944E // "mBIN" +#define MDOCBDTLID 0x6d424454 // "mBDT" +#define CI2IDENTIFIER 0x00434932 // "CI2" +#define OTGIDENTIFIER 0x554F5447 // "UOTG" +#define INVALIDID 0x21212121 // "!!!!" Should never appear in actual TIM file +#define PARTIONIDENTIFIER 0x50415254 // "PART" +// identifier for common tools Marvell Format image file +#define FBFIDENTIFIER 0x46424649 // "FBFI" Should never appear in actual TIM file + + +// Miscellanous +#define BINDKEYSIZE 128 // (MAXKEYSIZEWORDS * 2) +#define FLASHSIGMASK 0x0000000F // mask off the 4 bits of platform state + + + + +typedef enum INSTRUCTION_OP_CODE_SPEC_E +{ + // Enums specify the following: + INSTR_NOP = 0, + INSTR_WRITE = 1, + INSTR_READ = 2 , + INSTR_DELAY = 3, + INSTR_WAIT_FOR_BIT_SET = 4, + INSTR_WAIT_FOR_BIT_CLEAR = 5, + INSTR_AND_VAL = 6, + INSTR_OR_VAL = 7, + // new DDR Script instructions + INSTR_SET_BITFIELD = 8, + INSTR_WAIT_FOR_BIT_PATTERN = 9, + INSTR_TEST_IF_ZERO_AND_SET = 10, + INSTR_TEST_IF_NOT_ZERO_AND_SET = 11, + INSTR_LOAD_SM_ADDR = 12, + INSTR_LOAD_SM_VAL = 13, + INSTR_STORE_SM_ADDR = 14, + INSTR_MOV_SM_SM = 15, + INSTR_RSHIFT_SM_VAL = 16, + INSTR_LSHIFT_SM_VAL = 17, + INSTR_AND_SM_VAL = 18, + INSTR_OR_SM_VAL = 19, + INSTR_OR_SM_SM = 20, + INSTR_AND_SM_SM = 21, + INSTR_TEST_SM_IF_ZERO_AND_SET = 22, + INSTR_TEST_SM_IF_NOT_ZERO_AND_SET = 23, + // conditional execution branch and subroutine call instructions + INSTR_LABEL = 24, + INSTR_TEST_ADDR_AND_BRANCH = 25, + INSTR_TEST_SM_AND_BRANCH = 26, + INSTR_BRANCH = 27, + // Interpreter Directives + INSTR_END = 28, + //Add/Subtract + INSTR_ADD_SM_VAL = 29, + INSTR_ADD_SM_SM = 30, + INSTR_SUB_SM_VAL = 31, + INSTR_SUB_SM_SM = 32, + INSTR_LOAD_SM_FROM_ADDR_IN_SM = 33, + INSTR_STORE_SM_TO_ADDR_IN_SM = 34, + // New values go above here + INSTRUCTION_OP_CODE_E_MAX, + + // These enums identify pseudo op code that + // are used by tools for syntax shortcuts. The + // bootrom does not recognize the pseudo op + // code. When TBB is writing the TIM.bin, the pseudo + // op codes are converted to one or more instructions + // using the above INSTRUCTION_OP_CODE_SPEC_T enums. + + // pseudo instruction op codes used only by tools + // Enums specify the following: + INSTRUCTION_PSEUDO_OP_CODE_E_MIN = 10000, + + INSTR_PP_WRITE = 10001, + INSTR_PP_TABLEHEADER = 10002, + // New values go above here + INSTRUCTION_PSEUDO_OP_CODE_E_MAX, + +} INSTRUCTION_OP_CODE_SPEC_T; + + typedef struct +{ + unsigned int InstructionId; // InstructionID determines # of params for defined instructions + unsigned int Parameter; // first of the variable sized list of Parameters[ MAX_NUMBER_PARAMS = 3 ] +} INSTRUCTION_S, *pINSTRUCTION_S; + + + +typedef struct +{ + unsigned int OpId; + unsigned int OpValue; +} TZ_OPERATION, *pTZ_OPERATION; + +typedef enum TZ_OPERATION_SPEC_E +{ + TZ_NOP = 0, // Enums specify the following: + TZ_CONFIG_ENABLE, // TZ config enable flag (1 = configure) + // New values go above here + TZ_OPERATION_SPEC_E_MAX +} TZ_OPERATION_SPEC_T; + + + typedef enum DDR_OPERATION_SPEC_E +{ + DDR_NOP = 0, // Enums specify the following: + DDR_INIT_ENABLE, // DDR init flag (1 = init) + DDR_MEMTEST_ENABLE, // DDR Memtest flag (1 = test) + DDR_MEMTEST_START_ADDR, // Memtest start addr (Current default is 0) + DDR_MEMTEST_SIZE, // NumBytes to test (Current default is 2K) + DDR_INIT_LOOP_COUNT, // Loop Count for initialization attempts + DDR_IGNORE_INST_TO, // Treat a time out waiting for a bit to set/clear + // as informational only, operation continues + // New values go above here + DDR_OPERATION_SPEC_E_MAX +} DDR_OPERATION_SPEC_T; + +/********** WTP Recognized Reserved Area Layout ******************************** +* +* WTPTP_Defined_Reserved_Format_ID \ This clues BR, OBM and DKB that the reserved area is in a known format +* Number of Reserved Area Packages / For each package there is a header, payload size and payload +* +* Header \ Indicates what type of a Reserved Area Package +* Size \ Size Comprises a single Reserved Area Package +* Payload / There may be any number of Packages so long as TIM/NTIM < 4KB +* / +* +* Header \ The Last one should be a Package with a Terminator Header +* Size / The size should be 8 bytes (the size of this package) +* +**********************************************************************************/ +typedef struct +{ + UINT_T WTPTP_Reserved_Area_ID; // This clues BR, OBM and DKB that the reserved area is in a known format + UINT_T NumReservedHeaders; // For each package there is a header, payload size and payload +}WTP_RESERVED_AREA, *pWTP_RESERVED_AREA; + +typedef struct +{ + UINT_T Identifier; // Identification of this reserved area entry + UINT_T Size; // Size = Payload Size + 2 words (8 bytes). +}WTP_RESERVED_AREA_HEADER, *pWTP_RESERVED_AREA_HEADER; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T bmRequestType; + UINT_T bRequest; + UINT_T wValue; + UINT_T wIndex; + UINT_T wLength; + UINT_T wData; // First word of the proceeding Data. Note, there may be more traialing data +} USB_VENDOR_REQ, *pUSB_VENDOR_REQ; // There is no restriction that data need be 32 bit aligned. + +typedef struct +{ + volatile int *Addr; + UINT_T Value; +}GPIO_DEF, *pGPIO_DEF; +// General Purpose Patch (GPPx) related structures +typedef struct +{ + unsigned int OpId; + unsigned int OpValue; +} GPP_OPERATION, *pGPP_OPERATION; + +typedef enum GPP_OPERATION_SPEC_E +{ + GPP_NOP = 0, // Enums specify the following: + GPP_IGNORE_INST_TO = 6, // Treat a time out waiting for a bit to set/clear + // as informational only, operation continues + // New values go above here + GPP_OPERATION_SPEC_E_MAX +} GPP_OPERATION_SPEC_T; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + unsigned int NumberOperations; + unsigned int NumberInstructions; + GPP_OPERATION GPP_Operations; // GPP_Op[NumberOperations]; + INSTRUCTION_S GPP_Instructions; // GPP_Instruction[NumberInstructions]; +} GPP_PACKAGE, *pGPP_PACKAGE; +// End General Purpose Patch related structures + + +#if 0 // requires general.h +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T XferLoc; //location to put the XFER table + UINT_T NumPairs; + XFER_DATA_PAIR_T pXferPairs[0]; +}}OPT_XFER_SET, *pOPT_XFER_SET; +#endif + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T Port; + UINT_T Enabled; // 1 - Enabled +}OPT_PROTOCOL_SET, *pOPT_PROTCOL_SET; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T EscSeqTimeOutMS; // Value is interpreted in milli secs. +}OPT_ESCAPE_SEQUENCE, *P_OPT_ESCAPE_SEQUENCE; + + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T Enable; // enable TR069 firmware upgrade or not + UINT_T FlashAddr; // flash address to store FBF header + UINT_T Magic; // Magic number of FBF header +}TR069_INFO, *pTR069_INFO; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T Type; +}DDR_Type, *pDDR_Type; + + +typedef struct +{ + UINT MFPR_address; + UINT MFPR_value; +} MFPR_PAIR_T, *pMFPR_PAIR_T; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T GPIO_number; //GPIO to check + UINT_T GPIO_trigger_val; //value of GPIO to trigger the escape sequence + UINT_T num_MFPR_pairs; //number of MFPR pairs contained in this package + MFPR_PAIR_T mfpr_pairs[1]; //MFPR address/value pairs: array will be of size 'num_MFPR_pairs" +} OPT_ESC_SEQ_v2, *P_OPT_ESC_SEQ_v2; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T NumGpios; + pGPIO_DEF GPIO; +}OPT_GPIO_SET, *pOPT_GPIO_SET; + +typedef struct +{ + UINT_T ResumeAddr; + UINT_T ResumeParam; + UINT_T ResumeFlag; +}OPT_RESUME_DDR_INFO, *pOPT_RESUME_DDR_INFO; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + OPT_RESUME_DDR_INFO ResumeDDRInfo; +// pOPT_RESUME_DDR_INFO pResumeDDRInfo; +}OPT_RESUME_SET, *pOPT_RESUME_SET; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T ACCR_VALUE; + UINT_T MDCNFG_VALUE; + UINT_T DDR_HCAL_VALUE; + UINT_T MDREFR_VALUE; +}OPT_DDR_SET, *pOPT_DDR_SET; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T ImageAddr; +// UINT_T ImageSize; +// UINT_T ImageCRC; +}OPT_RESM_LOC, *pOPT_RESM_LOC; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; + UINT_T AutoBind; +}OPT_AUTOBIND, *pOPT_AUTOBIND; + +/**** Used only for backwards compatability!!! ***/ +typedef struct +{ + UINT_T Identifier; + UINT_T PortType; + UINT_T Port; + UINT_T GPIOPresent; + UINT_T NumGpios; + pGPIO_DEF GPIO; +}OPT_SET, *pOPT_SET; + +//mDOC general formatting parameters +// look in flstruct.h and flcommon.h +// for parameter definitions +// not spelled out here +//---------------------------------- +typedef struct +{ /* byte totals */ + WTP_RESERVED_AREA_HEADER WRAH; /*0x08 bytes */ + UINT_T percentUse; /*0x0C */ /* NAND flash inherently contains some bad blocks. TrueFFS handles + * those blocks by managing a pool of spare blocks also called transfer + * units. This format parameter specifies the percentage of the media + * to use. Starting from TrueFFS 6.3.0 alpha 4 this field is no longer a + * configurable formatting argument. You must set this field to + * TL_DEFAULT_PERCENTAGE = 0, letting TrueFFS to choose this value for you. */ + UINT_T noOfBDTLPartitions; /*0x10 */ /* Indicates the number of Disk partition (1 to 4). */ + UINT_T noOfBinaryPartitions; /*0x14 */ /* Indicates the number of binary partitions (up to 3). 0 will + * cause formatting with no binary partition. This value is ignored + * if TL_LEAVE_BINARY_AREA flag is set in the irFlags field the ioreq */ + UINT_T cascadedDeviceNo; /*0x18*/ /* Not used */ + UINT_T noOfCascadedDevices; /*0x1C*/ /* Not used */ + UINT_T progressCallback; /*0x20*/ /* Progress callback routine, will be called if not NULL. + The callback routine is called after erasing each unit, + and its parameters are the total number of erase units + to format and the number erased so far. + The callback routine returns a Status value. A value of + OK (0) allows formatting to continue. Any other value + will abort the formatting with the returned status code. */ + /* In case the FL_REPORT_MOUNT_PROGRESS compilation flag is set the + routine will also report the mount progress of the mount routine + for each of the Disk partitions. A 0,0 return values will report + the end of a format status and of a mount operation */ + UINT_T FP_0_RFU_0; /*0x24*/ /* Reserved 0 */ + UINT_T FP_1_RFU_0; /*0x28*/ /* Reserved 0 */ + + /* Note the following section is not used by for DiskOnChips */ + /*************************************************************/ + UINT_T bootImageLen; /*0x2C*/ /* Reserved 0 */ + UINT_T vmAddressingLimit; /*0x30*/ /* Reserved 0 */ + UINT_T embeddedCISlength; /*0x34*/ /* Reserved 0 */ + UINT_T *embeddedCIS; /*0x38*/ /* Reserved NULL */ +}MDOC_FORMAT_INFO, *pMDOCFORMAT_INFO; + +//mDOC BDTL partition type +//------------------------ +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; /*0x08 bytes */ + UINT_T length; /*0x0c */ /* The size in bytes of the usable storage space. The size + rounded upwards to a multiplication of a block size. + The size of the last partition will calculated automatically, + but if the requested size is greater then the remaining space + an error code will be returned,. Requesting zero size for any + partition but the last will generate an flBadParameters status. */ + + UINT_T fastAreaLength; /*0x10*/ + UINT_T lengthType; /*0x14*/ + UINT_T fastAreaLengthType; /*0x18*/ + UINT_T fastAreaVirtualFactor; /*0x1C*/ /* Should be set to FL_NORMAL_SPACING = 1 */ + UINT_T noOfSpareUnits; /*0x20*/ /* BDTL needs at least one spare erase unit in order to function + as a read/write media. It is possible to specify more than one + spare unit, which takes more media space. The advantage of + specifying more than one spare unit is that if one of the flash + erase units becomes bad and un-erasable in the future, then one + of the spare units can replace it. In that case, a second spare + unit enables TrueFFS to continue its read/write functionality, + whereas if no second spare unit is available the media goes into + read-only mode. The standard value used is 3 */ + + UINT_T BDTLFP_0_RFU_0; /*0x24*/ /* Reserved 0 */ + UINT_T BDTLFP_1_RFU_0; /*0x28*/ /* Reserved 0 */ + UINT_T BDTLFP_2_RFU_0; /*0x2C*/ /* Reserved 0 */ + UINT_T BDTLFP_3_RFU_0; /*0x30*/ /* Reserved 0 */ + UINT_T protectionKey[8]; /*0x50*/ /* The key for the protection*/ + UINT_T protectionType; /*0x54*/ /* PROTECTABLE - Can receive protection */ + /* READ_PROTECTED - Protect against read operations */ + /* WRITE_PROTECTED - Protect against write operations */ + /* LOCK_ENABLED - Enables the hardware lock signal */ + /* PROTECTABLE - This partition can be protected */ + /* CHANGEABLE_PROTECTION - protection type can be changed */ + /* The ratio between the real media size and the virtual size + reported to the file system when compression is active. */ + +}MDOC_BDTL_PARTITION, *pMDOC_BDTL_PARTITION; + +//mDOC binary partition type +//------------------------ +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; /*0x08 bytes */ + UINT_T length; /*0x0c*/ /* Required number of usable bytes (rounded to units) */ + /* in the partition. */ + + UINT_T lengthType; /*0x10*/ /* Must be FL_LENGTH_IN_BYTES = 0 */ + UINT_T sign[4]; /*0x20*/ /* signature of the binary partition to format. Typically "BIPO" + The signature 0xFFFF FFFF is not a valid signature */ + + UINT_T flags; /*0x24*/ /* TL_NORMAL_FORMAT=0 / TL_SPL_FORMAT=0xF0 */ + UINT_T spareBlocks; /*0x28*/ /* Spare blocks for DBB support, should be at least 1 */ + UINT_T BDKFP_0_RFU_0; /*0x2C*/ /* Reserved 0 */ + UINT_T BDKFP_1_RFU_0; /*0x30*/ /* Reserved 0 */ + UINT_T BDKFP_2_RFU_0; /*0x34*/ /* Reserved 0 */ + UINT_T BDKFP_3_RFU_0; /*0x38*/ /* Reserved 0 */ + UINT_T protectionKey[8]; /*0x58*/ /* The key for the protection*/ + UINT_T protectionType; /*0x5C*/ /* PROTECTABLE - Can receive protection */ + /* READ_PROTECTED - Protect against read operations */ + /* WRITE_PROTECTED - Protect against write operations */ + /* LOCK_ENABLED - Enables the hardware lock signal */ + /* PROTECTABLE - This partition can be protected */ + /* CHANGEABLE_PROTECTION - protection type can be changed */ +}MDOC_BINARY_PARTITION, *pMDOC_BINARY_PARTITION; + +/*********************************************************************************/ + +typedef enum +{ + PlatformVerificationKey, + NetworkOperatorCAKey, + SoftwareUpdateCAKey, + DRMDeviceCAKey, + OEMReservedKey1, + OEMReservedKey2, + NUMKEYMODULES +} +KEYMODULES_T; + +typedef enum +{ + Marvell_DS = 0, + PKCS1_v1_5_Caddo = 1, + PKCS1_v2_1_Caddo = 2, + PKCS1_v1_5_Ippcp = 3, + PKCS1_v2_1_Ippcp = 4, + ECDSA_256 = 5, + ECDSA_521 = 6 +} +ENCRYPTALGORITHMID_T; + +#define Intel_DS Marvell_DS + +typedef enum +{ + MRVL_SHA160 = 20, + MRVL_SHA256 = 32, + MRVL_SHA512 = 64 +} +HASHALGORITHMID_T; + +typedef struct +{ + UINT_T Version; + UINT_T Identifier; // "TIMH" + UINT_T Trusted; // 1- Trusted, 0 Non + UINT_T IssueDate; + UINT_T OEMUniqueID; +} VERSION_I, *pVERSION_I; // 0x10 bytes + +typedef struct +{ + UINT_T WTMFlashSign; + UINT_T WTMEntryAddr; + UINT_T WTMEntryAddrBack; + UINT_T WTMPatchSign; + UINT_T WTMPatchAddr; + UINT_T BootFlashSign; +} FLASH_I, *pFLASH_I; // 0x10 bytes + +typedef struct +{ + UINT_T KeyID; // Associate an ID with this key + UINT_T HashAlgorithmID; // See HASHALGORITHMID_T + UINT_T ModulusSize; // 1024 bit or 2048 bit keys + UINT_T PublicKeySize; + UINT_T RSAPublicExponent[MAXKEYSIZEWORDS]; // Contents depend on PublicKeySize + UINT_T RSAModulus[MAXKEYSIZEWORDS];// Up to 2K bits + UINT_T KeyHash[8]; // Reserve 256 bits for the hash +} KEY_MOD, *pKEY_MOD; // 0x22C bytes + +typedef struct +{ + UINT_T ImageID; // Indicate which Image + UINT_T NextImageID; // Indicate next image in the chain + UINT_T FlashEntryAddr; // Block numbers for NAND + UINT_T LoadAddr; + UINT_T ImageSize; + UINT_T ImageSizeToHash; + UINT_T HashAlgorithmID; // See HASHALGORITHMID_T + UINT_T Hash[8]; // Reserve 256 bits for the hash + UINT_T PartitionNumber; // This is new for V3.2.0 +} IMAGE_INFO_3_2_0, *pIMAGE_INFO_3_2_0; // 0x40 bytes + +typedef struct +{ + UINT_T ImageID; // Indicate which Image + UINT_T NextImageID; // Indicate next image in the chain + UINT_T FlashEntryAddr; // Block numbers for NAND + UINT_T LoadAddr; + UINT_T ImageSize; + UINT_T ImageSizeToHash; + UINT_T HashAlgorithmID; // See HASHALGORITHMID_T + UINT_T Hash[8]; // Reserve 256 bits for the hash +} IMAGE_INFO_3_1_0, *pIMAGE_INFO_3_1_0; // 0x3C bytes + +typedef struct +{ + UINT_T ImageID; // Indicate which Image + UINT_T NextImageID; // Indicate next image in the chain + UINT_T FlashEntryAddr; // Block numbers for NAND + UINT_T LoadAddr; + UINT_T ImageSize; + UINT_T ImageSizeToHash; + UINT_T HashAlgorithmID; // See HASHALGORITHMID_T + UINT_T Hash[16]; // Reserve 512 bits for the hash, this is new for V3.4.0 + UINT_T PartitionNumber; +} IMAGE_INFO_3_4_0, *pIMAGE_INFO_3_4_0; // 0x60 bytes + +typedef struct +{ + UINT_T ImageID; // Indicate which Image + UINT_T NextImageID; // Indicate next image in the chain + UINT_T FlashEntryAddr; // Block numbers for NAND + UINT_T LoadAddr; + UINT_T ImageSize; + UINT_T ImageSizeToHash; + HASHALGORITHMID_T HashAlgorithmID; // See HASHALGORITHMID_T + UINT_T Hash[16]; // Reserve 512 bits for the hash + UINT_T PartitionNumber; + ENCRYPTALGORITHMID_T EncAlgorithmID; // See ENCRYPTALGORITHMID_T + UINT_T EncryptStartOffset; + UINT_T EncryptSize; +} IMAGE_INFO_3_5_0, *pIMAGE_INFO_3_5_0; // 0x60 bytes + +typedef struct +{ + UINT_T KeyID; // Associate an ID with this key + UINT_T HashAlgorithmID; // 160 - SHA1, 256 - SHA2 + UINT_T KeySize; // Specified in bits + UINT_T PublicKeySize; // Specified in bits + UINT_T RSAPublicExponent[MAXRSAKEYSIZEWORDS]; // Contents depend on PublicKeySize + UINT_T RSAModulus[MAXRSAKEYSIZEWORDS]; // Up to 2K bits + UINT_T KeyHash[8]; // Reserve 256 bits for the hash +} KEY_MOD_3_1_0, *pKEY_MOD_3_1_0; // 0x22C bytes +typedef struct +{ + UINT_T KeyID; // Associate an ID with this key + HASHALGORITHMID_T HashAlgorithmID; // See HASHALGORITHMID_T + UINT_T KeySize; // Specified in bits + UINT_T PublicKeySize; // Specified in bits + UINT_T RSAPublicExponent[MAXRSAKEYSIZEWORDS]; // Contents depend on PublicKeySize + UINT_T RSAModulus[MAXRSAKEYSIZEWORDS]; // Up to 2K bits + UINT_T KeyHash[8]; // Reserve 256 bits for the hash +} KEY_MOD_3_2_0, *pKEY_MOD_3_2_0; // 0x22C bytes + +#if RVCT +#pragma anon_unions +#endif +typedef struct +{ + UINT_T KeyID; // Associate an ID with this key + HASHALGORITHMID_T HashAlgorithmID; // See HASHALGORITHMID_T + UINT_T KeySize; // Specified in bits + UINT_T PublicKeySize; // Specified in bits + ENCRYPTALGORITHMID_T EncryptAlgorithmID; // See ENCRYPTALGORITHMID_T; + union + { + struct + { + UINT_T RSAPublicExponent[MAXRSAKEYSIZEWORDS]; // Contents depend on PublicKeySize + UINT_T RSAModulus[MAXRSAKEYSIZEWORDS]; // Up to 2K bits + }Rsa; + + struct + { + UINT_T PublicKeyCompX[MAXECCKEYSIZEWORDS]; // Contents depend on PublicKeySize + UINT_T PublicKeyCompY[MAXECCKEYSIZEWORDS]; // Up to 521 bits + // Pad this struct so it remains consistent with RSA struct + UINT_T Reserved[(2*MAXRSAKEYSIZEWORDS)-(2*MAXECCKEYSIZEWORDS)]; + }Ecdsa; + }; + + UINT_T KeyHash[8]; // Reserve 256 bits for the hash +} KEY_MOD_3_3_0, *pKEY_MOD_3_3_0; // + + +// use EncryptedBitMask to access bit 31 of EncryptedAlgorithmID +// if bit 31 == 0 the access KEY_MOD_3_4_0 using the Rsa or Ecdsa structs +// if bit 31 == 1 the access KEY_MOD_3_4_0 using the EncryptedRsa or Encrypted Ecdsa structs +#define EncryptedBitMask 0x80000000 +typedef struct +{ + UINT_T KeyID; // Associate an ID with this key + HASHALGORITHMID_T HashAlgorithmID; // See HASHALGORITHMID_T + UINT_T KeySize; // Specified in bits + UINT_T PublicKeySize; // Specified in bits + ENCRYPTALGORITHMID_T EncryptAlgorithmID; // See ENCRYPTALGORITHMID_T; + union + { + struct + { + UINT_T RSAPublicExponent[MAXRSAKEYSIZEWORDS]; // Contents depend on PublicKeySize + UINT_T RSAModulus[MAXRSAKEYSIZEWORDS]; // Up to 2K bits + }Rsa; + + struct + { + UINT_T PublicKeyCompX[MAXECCKEYSIZEWORDS]; // Contents depend on PublicKeySize + UINT_T PublicKeyCompY[MAXECCKEYSIZEWORDS]; // Up to 521 bits + // Pad this struct so it remains consistent with RSA struct + UINT_T Reserved[(2*MAXRSAKEYSIZEWORDS)-(2*MAXECCKEYSIZEWORDS)]; + }Ecdsa; + + struct + { + UINT_T EncryptedHashRSAPublicExponent[MAXRSAKEYSIZEWORDS]; // Contents depend on PublicKeySize + UINT_T EncryptedHashRSAModulus[MAXRSAKEYSIZEWORDS]; // Up to 2K bits + }EncryptedRsa; + + struct + { + UINT_T EncryptedHashPublicKeyCompX_R[MAXECCKEYSIZEWORDS]; // Contents depend on PublicKeySize + UINT_T EncryptedHashPublicKeyCompX_S[MAXECCKEYSIZEWORDS]; // Contents depend on PublicKeySize + + UINT_T EncryptedHashPublicKeyCompY_R[MAXECCKEYSIZEWORDS]; // Up to 521 bits + UINT_T EncryptedHashPublicKeyCompY_S[MAXECCKEYSIZEWORDS]; // Up to 521 bits + + // Pad this struct so it remains consistent with encrypted RSA struct + UINT_T Reserved[(2 * MAXRSAKEYSIZEWORDS)-(4 * MAXECCKEYSIZEWORDS)]; + }EncryptedEcdsa; + }; + + UINT_T KeyHash[16]; // Reserve 512 bits for the hash +} KEY_MOD_3_4_0, *pKEY_MOD_3_4_0; // + + + +typedef struct +{ + ENCRYPTALGORITHMID_T DSAlgorithmID; // See ENCRYPTALGORITHMID_T + HASHALGORITHMID_T HashAlgorithmID; // See HASHALGORITHMID_T + UINT_T KeySize; // Specified in bits + UINT_T Hash[8]; // Reserve 256 bits for the hash + union // Note that this union should not be included as part of the hash for TIM in the Digital Signature + { + struct + { + UINT_T RSAPublicExponent[MAXRSAKEYSIZEWORDS]; + UINT_T RSAModulus[MAXRSAKEYSIZEWORDS]; // Up to 2K bits + UINT_T RSADigS[MAXRSAKEYSIZEWORDS]; // Contains TIM Hash + }Rsa; + struct + { + UINT_T ECDSAPublicKeyCompX[MAXECCKEYSIZEWORDS]; // Allow for 544 bits (17 words, 68 bytes for use with EC-521) + UINT_T ECDSAPublicKeyCompY[MAXECCKEYSIZEWORDS]; + UINT_T ECDSADigS_R[MAXECCKEYSIZEWORDS]; + UINT_T ECDSADigS_S[MAXECCKEYSIZEWORDS]; + UINT_T Reserved[(MAXRSAKEYSIZEWORDS*3)-(MAXECCKEYSIZEWORDS*4)]; + } Ecdsa; + }; +} PLAT_DS, *pPLAT_DS; // 0x780 bytes + +// Constant part of the TIMs +typedef struct +{ + VERSION_I VersionBind; // 0 + FLASH_I FlashInfo; // 0x10 + UINT_T NumImages; // 0x20 + UINT_T NumKeys; // 0x24 + UINT_T SizeOfReserved; // 0x28 +} CTIM, *pCTIM; // 0x2C + +// TIM structure for use by DKB/OBM/BootROM +/*typedef struct +{ + pCTIM pConsTIM; // Constant part + pIMAGE_INFO pImg; // Pointer to Images + pKEY_MOD pKey; // Pointer to Keys + PUINT pReserved; // Pointer to Reserved Area + pPLAT_DS pTBTIM_DS; // Pointer to Digital Signature +} +TIM, *pTIM;*/ + +// NTIM structure for use by DKB/OBM/BootROM +typedef struct +{ + pCTIM pConsTIM; // Constant part + pIMAGE_INFO_3_1_0 pImg; // Pointer to Images + PUINT pReserved; // Pointer to Reserved Area +} NTIM_3_1_0, *pNTIM_3_1_0; +typedef struct +{ + pCTIM pConsTIM; // Constant part + pIMAGE_INFO_3_2_0 pImg; // Pointer to Images + PUINT pReserved; // Pointer to Reserved Area +} NTIM_3_2_0, *pNTIM_3_2_0; +typedef struct +{ + pCTIM pConsTIM; // Constant part + pIMAGE_INFO_3_4_0 pImg; // Pointer to Images + PUINT pReserved; // Pointer to Reserved Area +} NTIM_3_4_0, *pNTIM_3_4_0; + + +// Defined for DTIM support 2012-3 + + + +typedef enum +{ + PRIMARYIMAGE = 0, // Primary image + RECOVERYIMAGE = 1, // Recovery image + CPIMAGE = 2 , // CP image + PPSETINGIMAG = 3, //PP Setting image + MARVELL_RESERVED_MAX = 9 , + CUSTMOZIEDIMAGE_TYPE1 = 10, + CUSTMOZIEDIMAGE_TYPE2 = 11, + CUSTMOZIEDIMAGE_TYPE3 = 12, + CUSTMOZIEDIMAGE_TYPE4 = 13, + CUSTMOZIEDIMAGE_TYPE5 = 14, + CUSTMOZIEDIMAGE_TYPE6 = 15, + CUSTMOZIEDIMAGE_TYPE7 = 16, + CUSTMOZIEDIMAGE_TYPE8 = 17, + CUSTMOZIEDIMAGE_TYPE9 = 18, + CUSTMOZIEDIMAGE_TYPE10 = 19, + CUSTMOZIEDIMAGE_TYPE11 = 20, + CUSTMOZIEDIMAGE_TYPE12 = 21, + CUSTMOZIEDIMAGE_TYPE13 = 22, + CUSTMOZIEDIMAGE_TYPE14 = 23, + CUSTMOZIEDIMAGE_TYPE15 = 24, + CUSTMOZIEDIMAGE_TYPE16 = 25, + CUSTMOZIEDIMAGE_TYPE17 = 26, + CUSTMOZIEDIMAGE_TYPE18 = 27, + CUSTMOZIEDIMAGE_TYPE19 = 28, + CUSTMOZIEDIMAGE_TYPE20 = 29, + CUSTMOZIEDIMAGE_TYPE_MAX = 50, +} OTA_IMAGE_TYPE; + +typedef struct +{ + UINT_T ImageID; // 0x54494Dxx - secondary tim ID (TIMx) + OTA_IMAGE_TYPE ImageType; // OTA_IMAGE_TYPE (Primary VS Recovery) + UINT_T FlashEntryAddr[2]; // Reserve 2 words for future compatibility + UINT_T PartitionNumber; // Partition # in the flash +} IMG_MAP_INFO, *pIMG_MAP_INFO; + +typedef struct +{ + WTP_RESERVED_AREA_HEADER WRAH; // Let it contain IMAP as package ID + UINT_T NumberOfMappedImages; // Number of images with mapping information + IMG_MAP_INFO pImgMapInfo[1]; // First image map information struct +} IMAGE_MAP, *pIMAGE_MAP; + + + +#endif + + + diff --git a/fbfdownloader/src/TimIncludedType.h b/fbfdownloader/src/TimIncludedType.h new file mode 100644 index 00000000..d43343f8 --- /dev/null +++ b/fbfdownloader/src/TimIncludedType.h @@ -0,0 +1,36 @@ +#pragma once + +typedef enum +{ + TIMH_NOTINC = 0, + TIMH_INC = 1, + DTIM_PRIMARY = 2, + DTIM_RECOVERY = 3, + DTIM_CP = 4, + TIMH_RECOVERYINC = 5, + DTIM_PPINFO = 6, + DTIM_CUSTMOZIEDTYPE1 = 10, + DTIM_CUSTMOZIEDTYPE2 = 11, + DTIM_CUSTMOZIEDTYPE3 = 12, + DTIM_CUSTMOZIEDTYPE4 = 13, + DTIM_CUSTMOZIEDTYPE5 = 14, + DTIM_CUSTMOZIEDTYPE6 = 15, + DTIM_CUSTMOZIEDTYPE7 = 16, + DTIM_CUSTMOZIEDTYPE8 = 17, + DTIM_CUSTMOZIEDTYPE9 = 18, + DTIM_CUSTMOZIEDTYPE10 = 19, + DTIM_CUSTMOZIEDTYPE11 = 20, + DTIM_CUSTMOZIEDTYPE12 = 21, + DTIM_CUSTMOZIEDTYPE13 = 22, + DTIM_CUSTMOZIEDTYPE14 = 23, + DTIM_CUSTMOZIEDTYPE15 = 24, + DTIM_CUSTMOZIEDTYPE16 = 25, + DTIM_CUSTMOZIEDTYPE17 = 26, + DTIM_CUSTMOZIEDTYPE18 = 27, + DTIM_CUSTMOZIEDTYPE19 = 28, + DTIM_CUSTMOZIEDTYPE20 = 29, + DKB_TIM = 100, + FBF_TIM = 101, + UNKOWN_TIMTYPE = 0xFF +} +TIMINCLUDEDTYPE_T; \ No newline at end of file diff --git a/fbfdownloader/src/Typedef.h b/fbfdownloader/src/Typedef.h new file mode 100644 index 00000000..616729cb --- /dev/null +++ b/fbfdownloader/src/Typedef.h @@ -0,0 +1,110 @@ +/****************************************************************************** + * + * (C)Copyright 2001-2009 Marvell. All Rights Reserved. + * + * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL. + * The copyright notice above does not evidence any actual or intended + * publication of such source code. + * This Module contains Proprietary Information of Marvell and should be + * treated as Confidential. + * The information in this file is provided for the exclusive use of the + * licensees of Marvell. + * Such users have the right to use, modify, and incorporate this code into + * products for purposes authorized by the license agreement provided they + * include this notice and the associated copyright notice with any such + * product. + * The information in this file is provided "AS IS" without warranty. + * + ******************************************************************************/ + +#ifndef _TYPEDEF_H_ +#define _TYPEDEF_H_ + + +#include "Macrodef.h" + +typedef volatile unsigned long VUINT32_T; +typedef unsigned long UINT32_T; +typedef volatile unsigned int VUINT_T; +typedef unsigned int UINT_T; +typedef int INT_T; +typedef unsigned short UINT16_T, USHORT; +typedef volatile unsigned short VUINT16_T; +typedef unsigned char UINT8_T; +typedef char INT8_T; +typedef int BOOL; + + + +#ifdef LINUX +typedef unsigned long *PDWORD; +typedef unsigned char *PBYTE; +typedef unsigned int UINT, *PUINT; // The size is not important +typedef unsigned long long UINT64, *PUINT64; +typedef unsigned int UINT32, *PUINT32; +typedef unsigned short UINT16, *PUINT16; +typedef unsigned char UINT8, *PUINT8; +typedef unsigned char UCHAR,BYTE,*PUCHAR; +typedef unsigned long DWORD; +typedef BYTE* LPBYTE; + +typedef int INT, *PINT; // The size is not important +typedef long long INT64, *PINT64; +typedef int INT32, *PINT32; +typedef short INT16, *PINT16; +typedef signed char INT8, *PINT8; +#define VOID void +#define PVOID void* +#else +#include "stdafx.h" +#endif + + +#define LOCKED 1 +#define UNLOCKED 0 + + + +typedef void(*FnPVOID)(void); + + + + + +typedef volatile UINT VUINT, *PVUINT; // The size is not important +typedef volatile UINT64 VUINT64, *PVUINT64; +typedef volatile UINT32 VUINT32, *PVUINT32; +typedef volatile UINT16 VUINT16, *PVUINT16; +typedef volatile UINT8 VUINT8, *PVUINT8; +typedef volatile UCHAR VUCHAR, *PVUCHAR; + +typedef volatile INT VINT, *PVINT; // The size is not important +typedef volatile INT64 VINT64, *PVINT64; +typedef volatile INT32 VINT32, *PVINT32; +typedef volatile INT16 VINT16, *PVINT16; +typedef volatile INT8 VINT8, *PVINT8; +typedef volatile CHAR VCHAR, *PVCHAR; + +typedef struct{ + UINT_T ErrorCode; + UINT_T StatusCode; + UINT_T PCRCode; +}FUNC_STATUS, *pFUNC_STATUS; + +#ifdef LINUX +#ifdef _UNICODE +#define My_strcpy(a,b,c) wcscpy(a,c) +#else +#define My_strcpy(a,b,c) strcpy(a,c) +#endif +#else +#ifdef _UNICODE +#define My_strcpy(a,b,c) _tcscpy_s(a,b,c) +#else +#define My_strcpy(a,b,c) strcpy(a,c) +#endif +#endif// LINUX + + + +#endif //_TYPEDEF_H_ diff --git a/fbfdownloader/src/UploadParaDef.h b/fbfdownloader/src/UploadParaDef.h new file mode 100644 index 00000000..a5a59652 --- /dev/null +++ b/fbfdownloader/src/UploadParaDef.h @@ -0,0 +1,62 @@ +#pragma once +#include "Macrodef.h" + +#pragma pack(push,1) +typedef struct _UPLOAD_DATA_PARAMS +{ + BYTE Type; + BYTE SubType; + BYTE Partition; + BYTE Times;// Total Number of upload Areas + unsigned int Offset; + unsigned int DataSize; + BYTE IncludeSpareAreas; // indicate this upload include spare areas or not + BYTE ResetUE; + BYTE ResetTimeDelay; + BYTE Reserved2; // 用来存放DataSize的高32位,支持一次性upload大于4GB的内容 + +} UPLOAD_DATA_PARAMS; +static void NEW_UPLOAD_DATA_PARAMS(UPLOAD_DATA_PARAMS *me){me->Reserved2 = 0;} +static void COPY_UPLOAD_DATA_PARAMS(UPLOAD_DATA_PARAMS *me,UPLOAD_DATA_PARAMS* UpLoadDataPara) + { + me->Type = UpLoadDataPara->Type; + me->SubType = UpLoadDataPara->SubType; + me->Partition = UpLoadDataPara->Partition; + me->Times = UpLoadDataPara->Times; + me->Offset = UpLoadDataPara->Offset; + me->DataSize = UpLoadDataPara->DataSize; + me->IncludeSpareAreas = UpLoadDataPara->IncludeSpareAreas; // indicate this upload include spare areas or not + me->ResetUE = UpLoadDataPara->ResetUE; + me->ResetTimeDelay = UpLoadDataPara->ResetTimeDelay; + me->Reserved2 = UpLoadDataPara->Reserved2; + } +#pragma pack(pop) + + +#pragma pack(push,1) +typedef struct _UPLOAD_DATA_SPEC +{ + UPLOAD_DATA_PARAMS m_Params; + kstring_t strOutputFileName; + kstring_t strComparisonFileName; + BOOL bCreateNewFile; +} UPLOAD_DATA_SPEC,*pUPLOAD_DATA_SPEC; +static void NewUPLOAD_DATA_SPEC(pUPLOAD_DATA_SPEC me,struct _UPLOAD_DATA_SPEC* UpLoadDataSpec) + { + me->m_Params = UpLoadDataSpec->m_Params; + me->strOutputFileName = UpLoadDataSpec->strOutputFileName; + me->strComparisonFileName = UpLoadDataSpec->strComparisonFileName; + me->bCreateNewFile = UpLoadDataSpec->bCreateNewFile; + } +#pragma pack(pop) + + + +#define __uds_free(x) + +KLIST_INIT(pudsl,UPLOAD_DATA_SPEC*,__uds_free) + + + +typedef klist_t(pudsl)* t_UpLoadDataSpecList; +typedef kliter_t(pudsl)* t_UpLoadDataSpecIter; \ No newline at end of file diff --git a/fbfdownloader/src/WTPCOMMCLASS.c b/fbfdownloader/src/WTPCOMMCLASS.c new file mode 100644 index 00000000..78cc6e81 --- /dev/null +++ b/fbfdownloader/src/WTPCOMMCLASS.c @@ -0,0 +1,1409 @@ +// WTPCOMMCLASS.cpp: implementation of the CWtpComm class. +// +////////////////////////////////////////////////////////////////////// +#include "./Macrodef.h" +#include +#include "WTPCOMMCLASS.h" +#include +#include +#include +#include +#include "WTPIOCTL.h" + +#include "ErrorCode.h" +#include +#include + + +const short PACKET_SIZE = 16376; // plus command makes 4096 +#define OPEN_RETRY 10 +////////////////////////////////////////////////////////////////////// +// Construction/Destruction +////////////////////////////////////////////////////////////////////// + +void NewCWtpComm (struct CWtpComm *me) +{ + NewCConvertLT2B(&(me->MyConvertLT2B)); + me->m_PortType = UNKNOWNPORT; + me->m_iPortNumber = 1; + me->m_ThreadExit = 0; + me->m_liTimeout = 0; + me->m_bVerbose = FALSE; + me->m_bMsg = FALSE; + me->MessageMode = DISABLED; + me->m_bBaudRateSet = FALSE; + me->m_bInterfaceSpecified = FALSE; + me->m_hLog = NULL; + me->m_uiPacketSize = PACKET_SIZE; + me->m_bfastDownload = GET; + me->m_blastData = GET; + me->m_bIsNonNewWTPTP = FALSE; +#if DEBUG_MODE + me->m_bDebugTrace = TRUE; +#else + me->m_bDebugTrace = FALSE; +#endif + +} + + +void CWtpCommSetBootDeviceType(struct CWtpComm *me,EDeviceType eType) +{ + me->m_DeviceType = eType; +} + +void SetPlatformType(struct CWtpComm *me,ePlatForm ePlatformType) +{ + me->m_PlatformType = ePlatformType; +} + +void SetPortType (struct CWtpComm *me,int iSelect) +{ + switch (iSelect) + { + case USB: + me->m_PortType = USB; + break; + + case SERIALPORT: + me->m_PortType = SERIALPORT; + break; + + default: + me->m_PortType = UNKNOWNPORT; + break; + } +} + +int GetPortType (struct CWtpComm *me) +{ + return me->m_PortType; +} + +void SetInterfaceName (struct CWtpComm *me,TCHAR* pInterfaceName) +{ + _tcscpy( me->m_szInterfaceName, pInterfaceName ); + me->m_bInterfaceSpecified = TRUE; +} + + +void SetUsbPortTimeout (struct CWtpComm *me,long int lTimeout) +{ + me->m_liTimeout = lTimeout; +} + +void SetPacketSize(struct CWtpComm *me, unsigned short uiSize ) +{ + me->m_uiPacketSize = (((uiSize+63)/64) * 64)-8; +} + +unsigned short GetPacketSize(struct CWtpComm *me) +{ + return me->m_uiPacketSize; +} + + +void SetMessageMode (struct CWtpComm *me,MESSAGE_MODES MessageModeOnOff) +{ + me->MessageMode = MessageModeOnOff; +} + +void HandleTraceLog(struct CWtpComm *me,const TCHAR* format,...) +{ + if(me->m_bDebugTrace) + { + char szBuffer[1024]; + va_list pArgs; + va_start (pArgs, format); + vsprintf (szBuffer, format, pArgs); + va_end (pArgs); + printf(szBuffer); + fprintf(me->m_hLog, szBuffer); + } +} +BOOL SendPreamble (struct CWtpComm *me,BOOL bIsCustPreamble) +{ + BOOL IsOk = TRUE; + WTPSTATUS* pWtpStatus = (WTPSTATUS*)malloc(sizeof(WTPSTATUS)); + memset( pWtpStatus, 0, sizeof(WTPSTATUS) ); + me->m_iSequence = 0x00; + + HandleTraceLog(me,_T("SendPreamble command\n")); + + WTPCOMMAND WtpCmd = {PREAMBLE,0xD3,0x02,0x2B,htole32(0x00D3022B)}; + IsOk = WriteUSB(me,&WtpCmd,4); + if(IsOk) + { + if(!ReadUSB (me,pWtpStatus,4+34)) + { + IsOk = FALSE; + } + + if (pWtpStatus->CMD != PREAMBLE && pWtpStatus->SEQ != 0xD3 && pWtpStatus->CID != 0x02) + { + IsOk = FALSE; +#if PRINTLOG + printf("SendPreamble returned a wrong status\n"); +#endif + fprintf(me->m_hLog, "SendPreamble returned a wrong status\n"); + } + if (pWtpStatus->Status == NACK) + { + IsOk = FALSE; +#if PRINTLOG + printf("Error: SendPreamble returned a NACK!\n"); +#endif + fprintf(me->m_hLog,"Error: SendPreamble returned a NACK!\n"); + } + + + HandleTraceLog(me,"ReadUSB is ok in sending preamble...\n"); + + + } + free( pWtpStatus); + return IsOk; +} + +BOOL GetVersion (struct CWtpComm *me,WTPSTATUS *pWtpStatus) +{ + HandleTraceLog(me,_T("GetVersion command......\n")); + BOOL IsOk = TRUE; + me->m_iSequence = 0x00; + WTPCOMMAND WtpCmd = {GETVERSION,me->m_iSequence,0x00,0x00,htole32(0x00000000)}; + memset( pWtpStatus, 0, sizeof(WTPSTATUS) ); + pWtpStatus->Flags = 0x01; + HandlePendingMessages(me,pWtpStatus); + + HandleTraceLog(me,_T("WriteUSB in GetVersion command\n")); + IsOk = WriteUSB (me,&WtpCmd,8); + + if(IsOk) + { + IsOk = FALSE; + HandleTraceLog(me,_T("ReadUSB in GetVersion command\n")); + IsOk = ReadUSB(me,pWtpStatus,30); + if(!IsOk) + { + HandleTraceLog(me,_T("ReadUSB failed in GetVersion command\n")); + return FALSE; + } + if (IsOk && pWtpStatus->Status == NACK) + { + IsOk = FALSE; +#if PRINTLOG + printf("Error: GetVersion returned a NACK!\n"); +#endif + fprintf(me->m_hLog,"Error: GetVersion returned a NACK!\n"); + } + + } + else + { + HandleTraceLog(me,_T("WriteUSB failed in GetVersion command\n")); + return FALSE; + } + + HandleTraceLog(me,_T("GetVersion command return\n")); + return IsOk; +} + +BOOL GetBadBlockInfo(struct CWtpComm *me,WTPSTATUS *pWtpStatus) +{ + BOOL IsOk = TRUE; + me->m_iSequence = 0x00; + WTPCOMMAND WtpCmd = {GETBADBLOCK,me->m_iSequence,0x00,0x00,htole32(0x00000000)}; + + if (kBootLoader == me->m_DeviceType) + { + memset( pWtpStatus, 0, sizeof(WTPSTATUS) ); + pWtpStatus->Flags = 0x01; + + HandlePendingMessages(me, pWtpStatus ); + + HandleTraceLog(me,_T("WriteUSB in GetBadBlockInfo command\n")); + IsOk = WriteUSB (me,&WtpCmd,8); + + if(IsOk) + + { + IsOk = FALSE; + HandleTraceLog(me,_T("ReadUSB in GetBadBlockInfo command\n")); + IsOk = ReadUSB(me,pWtpStatus,6+sizeof(BadBlockData)); + if(!IsOk) + { + HandleTraceLog(me,_T("ReadUSB failed in GetBadBlockInfo command\n")); + return FALSE; + } + } + else + { + HandleTraceLog(me,_T("WriteUSB failed in GetBadBlockInfo command\n")); + return FALSE; + } + + if (pWtpStatus->Status == NACK) + { + IsOk = FALSE; +#if PRINTLOG + printf("Error: GetVersion returned a NACK!\n"); +#endif + + tfprintf(me->m_hLog,"Error: GetVersion returned a NACK!\n"); + } + + fflush(me->m_hLog); + } + return IsOk; +} + +BOOL GetImageCrc(struct CWtpComm *me,WTPSTATUS *pWtpStatus) +{ + BOOL IsOk = TRUE; + me->m_iSequence = 0x00; + WTPCOMMAND WtpCmd = {GETIMAGECRC,me->m_iSequence,0x00,0x00,htole32(0x00000000)}; + + if (kBootLoader == me->m_DeviceType) + { + memset( pWtpStatus, 0, sizeof(WTPSTATUS) ); + pWtpStatus->Flags = 0x01; + + HandlePendingMessages(me, pWtpStatus ); + + HandleTraceLog(me,_T("WriteUSB in GetImageCrc command\n")); + IsOk = WriteUSB (me,&WtpCmd,8); + + if(IsOk) + + { + IsOk = FALSE; + HandleTraceLog(me,_T("ReadUSB in GetImageCrc command\n")); + IsOk = ReadUSB(me,pWtpStatus,6+sizeof(ImageCRCInfo)); + if(!IsOk) + { + HandleTraceLog(me,_T("ReadUSB failed in GetImageCrc command\n")); + return FALSE; + } + } + else + { + HandleTraceLog(me,_T("WriteUSB failed in GetImageCrc command\n")); + return FALSE; + } + + if (pWtpStatus->Status == NACK) + { + IsOk = FALSE; + tfprintf(me->m_hLog,_T("Error: GetImageCrc returned a NACK!\n")); + } + + fflush(me->m_hLog); + } + return IsOk; +} + + +BOOL SelectImage (struct CWtpComm *me,UINT32 *pImageType) +{ + HandleTraceLog(me,_T("SelectImage command\n")); + WTPCOMMAND WtpCmd = {SELECTIMAGE,0x00,0x00,0x00,htole32(0x00000000)}; + WTPSTATUS* pWtpStatus = (WTPSTATUS*)malloc(sizeof(WTPSTATUS)); + memset( pWtpStatus, 0, sizeof(WTPSTATUS) ); + BOOL Isok = TRUE; + HandlePendingMessages(me, pWtpStatus ); + + if (WriteUSB (me,&WtpCmd,8) == FALSE) + Isok = FALSE; + if (Isok) + { + if(ReadUSB (me,pWtpStatus,10) == FALSE) + { + Isok = FALSE; + } + else + { + if (pWtpStatus->Status == NACK) + { + Isok = FALSE; +#if PRINTLOG + printf("Error: SelectImage returned a NACK!\n"); +#endif + fprintf(me->m_hLog,"Error: SelectImage returned a NACK!\n"); + } + if(me->m_bDebugTrace) + { + for(int i =0; i<4; i++) + tprintf(_T("pWtpStatus->Data[%d] =%c\n"),i,pWtpStatus->Data[i]); + } + *pImageType = pWtpStatus->Data[0]; + *pImageType |= pWtpStatus->Data[1] << 8; + *pImageType |= pWtpStatus->Data[2] << 16; + *pImageType |= pWtpStatus->Data[3] << 24; + + } + } + + HandlePendingMessages(me, pWtpStatus ); + free( pWtpStatus); + pWtpStatus = NULL; + + HandleTraceLog(me,_T("SelectImage command return\n")); + return Isok; +} + + +BOOL VerifyImage (struct CWtpComm *me,BYTE AckOrNack) +{ + HandleTraceLog(me,_T("VerifyImage command\n")); + + BOOL IsOk = TRUE, EnableMessages = TRUE; + me->m_iSequence = 0x00; + WTPCOMMAND WtpCmd = {VERIFYIMAGE,me->m_iSequence,0x00,0x00,htole32(0x00000001),AckOrNack}; + WTPSTATUS* pWtpStatus = (WTPSTATUS*)malloc(sizeof(WTPSTATUS)); + DWORD BytesRead = 0; + memset( pWtpStatus, 0, sizeof(WTPSTATUS) ); + //HandlePendingMessages( pWtpStatus ); + + if (WriteUSB (me,&WtpCmd,9) == FALSE) + IsOk = FALSE; + if(IsOk) + { + if (ReadUSB (me,pWtpStatus,6) == FALSE) + { + IsOk = FALSE; + } + } + + if (AckOrNack == NACK) + { + IsOk = FALSE; +#if PRINTLOG + printf(_T("\nError: Image asked for by target does not exist!")); +#endif + tfprintf (me->m_hLog,_T("\nError: Image asked for by target does not exist!")); + } + if (pWtpStatus->Status == NACK) + { + IsOk = FALSE; +#if PRINTLOG + printf(_T("\nError: VerifyImage returned a NACK!")); +#endif + tfprintf (me->m_hLog,_T("\nError: VerifyImage returned a NACK!")); + } + + HandlePendingMessages(me,pWtpStatus ); + free( pWtpStatus); + pWtpStatus = NULL; + + HandleTraceLog(me,_T("VerifyImage command return\n")); + return IsOk; +} + +BOOL DataHeader (struct CWtpComm *me,unsigned int uiRemainingData,WTPSTATUS *pWtpStatus,BOOL bFastDownload) +{ + HandleTraceLog(me,_T("DataHeader command\n")); + + BOOL IsOk = TRUE; + WTPCOMMAND WtpCmd = {DATAHEADER,++me->m_iSequence,0x00,0x00,htole32(4)}; + DWORD BytesRead = 0, StatusLength = 0; + /* Fix me please. getFastDownload is buggy*/ + if(me->m_bDebugTrace) + { + tfprintf (me->m_hLog,_T("\nDataHeader command, uiRemainingData size:%d\n"),uiRemainingData); + } + + //if (isFastDownload(GET, FDMODE)) + if (bFastDownload) + WtpCmd.Flags = 0x4; + + HandlePendingMessages(me, pWtpStatus ); + WtpCmd.Data[0] = uiRemainingData & 0x000000FF; + WtpCmd.Data[1] = (uiRemainingData & 0x0000FF00) >> 8; + WtpCmd.Data[2] = (uiRemainingData & 0x00FF0000) >> 16; + WtpCmd.Data[3] = (uiRemainingData & 0xFF000000) >> 24; + pWtpStatus->Status = ACK; + + if (WriteUSB (me,&WtpCmd,12) == FALSE) + IsOk = FALSE; + if(IsOk) + { + //make workaround for helan2 bootrom download,05/06/2014,llzhou + if(PLAT_HELAN2 == me->m_PlatformType) + { + usleep(20000); + } + + if (ReadUSB (me,pWtpStatus,10) == FALSE) + { + IsOk = FALSE; + } + else + { + if (pWtpStatus->Status == NACK) + { + IsOk = FALSE; +#if PRINTLOG + printf("Error: DataHeader returned a NACK!\n"); +#endif + fprintf(me->m_hLog,"Error: DataHeader returned a NACK!\n"); + } + if(me->m_bDebugTrace) + { + for(int i =0; i<4; i++) + tprintf(_T("pWtpStatus->Data[%d] =%d\n"),i,pWtpStatus->Data[i]); + } + + } + } + + HandlePendingMessages(me, pWtpStatus ); + + HandleTraceLog(me,_T("DataHeader command return\n")); + + return IsOk; +} + +BOOL Data (struct CWtpComm *me,PBYTE pData,UINT32 Length) +{ + HandleTraceLog(me,_T("Data command\n")); + + BOOL IsOk = TRUE; + WTPCOMMAND WtpCmd = {DATA,++me->m_iSequence,0x00,0x00,htole32(Length)}; + WTPSTATUS* pWtpStatus = (WTPSTATUS*)malloc(sizeof(WTPSTATUS)); + DWORD BytesRead = 0; + unsigned int tmp = 0; + BOOL bFoundChar = TRUE; + + memset( pWtpStatus, 0, sizeof(WTPSTATUS) ); + // HandlePendingMessages( pWtpStatus ); + if (isFastDownload (me,GET, FDMODE)) + { + HandleTraceLog(me,_T("Begin WriteUSBWithNoRsp\n")); + if (WriteUSBWithNoRsp (me,pData,(DWORD)Length) ) + { + HandleTraceLog(me,_T("Finish WriteUSBWithNoRsp\n")); + if (isLastData(me,GET, FDMODE)) + { + HandleTraceLog(me,_T("Begin ReadUSB\n")); + if(!ReadUSB (me,pWtpStatus,6)) + { + free( pWtpStatus); + return FALSE; + } + HandleTraceLog(me,_T("Finish ReadUSB\n")); + + if(pWtpStatus->CMD!=WtpCmd.CMD&&pWtpStatus->Status == NACK) + { + free( pWtpStatus); + return FALSE; + } + + if(me->m_bDebugTrace) + { + tprintf (_T("\nBytesRead : %lu GetWTPMESSAGE:%x %x %x %x %x %x \n"), + BytesRead, + pWtpStatus->CMD, + pWtpStatus->SEQ, + pWtpStatus->CID, + pWtpStatus->Status, + pWtpStatus->Flags, + pWtpStatus->DLEN); + } + + } + } + else + { + IsOk = FALSE; + } + + } + else + { + memcpy(WtpCmd.Data,pData,Length); + HandleTraceLog(me,_T("Begin WriteUSB\n")); + if (WriteUSB (me,&WtpCmd,8 + (DWORD)Length) == FALSE) + { + IsOk = FALSE; + } + else + { + HandleTraceLog(me,_T("Begin ReadUSB\n")); + if (ReadUSB (me,pWtpStatus,6) == FALSE) + { + IsOk = FALSE; + } + } + + } + + HandlePendingMessages(me, pWtpStatus ); + free( pWtpStatus); + pWtpStatus = NULL; + + HandleTraceLog(me,_T("Data command return\n")); + + return IsOk; + +} + +BOOL Done (struct CWtpComm *me) +{ + + HandleTraceLog(me,_T("Done command\n")); + + BOOL IsOk = TRUE, EnableMessages = TRUE; + me->m_iSequence = 0x00; + WTPCOMMAND WtpCmd = {DONE,me->m_iSequence,0x00,0x00,htole32(0x00000000)}; + WTPSTATUS* pWtpStatus = (WTPSTATUS*)malloc(sizeof(WTPSTATUS)); + DWORD BytesRead = 0; + + memset( pWtpStatus, 0, sizeof(WTPSTATUS) ); + pWtpStatus->Flags = 0x01; + HandlePendingMessages(me, pWtpStatus ); + if (WriteUSB (me,&WtpCmd,8) == FALSE) + IsOk = FALSE; + if (ReadUSB(me,pWtpStatus,6) == FALSE) + { + IsOk = FALSE; + } + else + { + if(pWtpStatus->CMD!=DONE) + { + if (WriteUSB (me,&WtpCmd,8) == FALSE) + IsOk = FALSE; + else + { + if (ReadUSB(me,pWtpStatus,6) == FALSE) + { + IsOk = FALSE; + } + // Sleep(100); + if (ReadUSB(me,pWtpStatus,6) == FALSE) + { + IsOk = FALSE; + } + + if(pWtpStatus->CMD!=DONE) + { + IsOk = FALSE; + } + + if (pWtpStatus->Status == NACK) + { + IsOk = FALSE; +#if PRINTLOG + printf ("Error: Done returned a NACK!"); +#endif + fprintf (me->m_hLog,"Error: Done returned a NACK!"); + } + } + + } + } + HandlePendingMessages(me, pWtpStatus ); + + free( pWtpStatus); + pWtpStatus = NULL; + + HandleTraceLog(me,_T("Done command return\n")); + + return IsOk; +} + +BOOL Disconnect (struct CWtpComm *me,WTPSTATUS* pWtpStatus) +{ + + BOOL IsOk = TRUE; + me->m_iSequence = 0x00; + WTPCOMMAND WtpCmd = {DISCONNECT,me->m_iSequence,0x00,0x00,htole32(0x00000000)}; + DWORD BytesRead; + HandlePendingMessages(me, pWtpStatus ); + + HandleTraceLog(me,_T("Disconnect command\n")); + + + if (!WriteUSB (me,&WtpCmd,8)) + { + IsOk = FALSE; + } + else + { + if (ReadUSB (me,pWtpStatus,6) == FALSE) + { + IsOk = FALSE; + } + if (pWtpStatus->Status == NACK) + { + //now try disconnect once more + pWtpStatus->Status = ACK; + + HandlePendingMessages(me, pWtpStatus ); + if (WriteUSB(me,&WtpCmd,8) == FALSE) + IsOk = FALSE; + if(IsOk) + { + if (ReadUSB(me,pWtpStatus,6) == FALSE) + { + IsOk = FALSE; + } + } + + } + } + HandlePendingMessages(me, pWtpStatus ); + + + if(IsOk == FALSE) + pWtpStatus->Status = NACK; + + + HandleTraceLog(me,_T("Disconnect command return\n")); + + return IsOk; + +} + + + +BOOL GetWtpMessage (struct CWtpComm *me,WTPSTATUS *pWtpStatus) +{ + //tfprintf (m_hLog,_T("\n GetWtpMessage..........\n")); + BOOL IsOk = TRUE, bFoundChar = TRUE; + me->m_iSequence = 0x00; + WTPCOMMAND WtpCmd = {MESSAGE,me->m_iSequence,0x00,0x00,htole32(0x00000000)}; + DWORD StatusLength, BytesRead; + TCHAR WtpMessage[MESSAGELENGTH]; + int i; + + memset (WtpMessage,'\0',MESSAGELENGTH); + + pWtpStatus->Status = NACK; + switch (me->m_PortType) + { + case USB: + { + if (!WriteUSB(me,&WtpCmd,8)) + { + IsOk = FALSE; + tfprintf (me->m_hLog,_T("\nWriteUsb failed in GetWtpMessage\n")); + } + else + { + if (pWtpStatus->DLEN > 0) + { + pWtpStatus->Status = ACK; + // IsOk = FALSE; + // return IsOk; + } + if (pWtpStatus->Status != ACK) + { + pWtpStatus->Status = NACK; + //IsOk = FALSE; + // return IsOk; + } + if (ReadUSB (me,pWtpStatus,6 + MESSAGELENGTH) == FALSE) + { + IsOk = FALSE; + } + else + { + switch(me->m_DeviceType) + { + case kBootLoader: + { + UINT32 ReturnCode = 0; + int i ; + for ( i = 0; i < 4; i++) + { + ReturnCode |= pWtpStatus->Data[i+2] << (8 * i); + } + if(pWtpStatus->Data[0]== WTPTPNOTIFICATION) + { + BOOL bFound = FALSE; + for (i = 0; i < MAXNOTIFICATIONSCODES; i++) + { + if (WTPTPNotificationMsg[i].NotificationCode == ReturnCode) + { +#ifndef COMPRESSDATA + tfprintf (me->m_hLog,_T("\nWTPTP Notification: %s 0x%X\n"),WTPTPNotificationMsg[i].Description,ReturnCode); +#else + tfprintf (me->m_hLog,_T("\nWTPTP Notification: 0x%X\n"),ReturnCode); +#endif + bFound = TRUE; + break;; + } + + } + if(!bFound) + { + tfprintf (me->m_hLog,_T("\nNotification Code: 0x%X\n"),ReturnCode); + } + } + else if(pWtpStatus->Data[0]== WTPTPERRORREPORT && kBootLoader == me->m_DeviceType) + { + TCHAR szMessage[1024]; + BOOL bFound = FALSE; + for (i = 0; i < MAXERRORCODES; i++) + { + if (WTPTPErrorCodes[i].ErrorCode == ReturnCode) + { + + + #ifndef COMPRESSDATA + tfprintf (me->m_hLog,_T("\nWTPTP Error: %s : Errorcode is 0x%X\n"),WTPTPErrorCodes[i].Description,ReturnCode); + #else + tfprintf (me->m_hLog,_T("\nWTPTP Errorcode is 0x%X\n"),ReturnCode); + #endif + bFound = TRUE; + break; + } + } + + if(!bFound) + { + + + tfprintf (me->m_hLog,_T("\nUser customized ErrorCode: 0x%X\n"),ReturnCode); + + + + } + + IsOk = FALSE; + + } + else if (WTPTPNOTIFICATION_UPLOAD == pWtpStatus->Data[0]) + { + tfprintf (me->m_hLog,_T("\nFlash_NandID: 0x%X\n"),ReturnCode); + } + else if (WTPTPNOTIFICATION_FLASHSIZE == pWtpStatus->Data[0]) + { + + tfprintf (me->m_hLog,_T("\nFlash_Size: 0x%X bytes\n"),ReturnCode); + } + } + break; + default: + break; + } + } + } + } + } + return IsOk; +} + +BOOL GetTargetMessage (struct CWtpComm *me,WTPSTATUS *pWtpStatus) +{ + + BOOL IsOk = TRUE; + unsigned long int Seconds = 0, DelayTime = 120; + + + while ( (pWtpStatus->Status == ACK) && Seconds m_hLog,_T("\n GetWtpMessage...\n")); + if (!GetWtpMessage (me,pWtpStatus)) + { + + IsOk = FALSE; + break; + } + + // This is to add a delay for WTPTP while DKB is busy on the target. + if (pWtpStatus->Data[0] == PlatformBusy && kBootLoader == me->m_DeviceType ) + { + do + { + GetWtpMessage(me,pWtpStatus); + + if ( pWtpStatus->Data[0] == PlatformDisconnect ) + break; + tfprintf (me->m_hLog,_T("\n usleep(2000000) in GetWtpMessage...\n")); + usleep(2000000); + Seconds += 2000; + + } + while(pWtpStatus->Data[0] != PlatformReady); + } + tfprintf (me->m_hLog,_T(" Platform ready status: %X\n"), pWtpStatus->Data[0]); + + if ( pWtpStatus->Data[0] == PlatformDisconnect ) + { + tfprintf (me->m_hLog,_T("Target requested disconnect!!!\n")); + return FALSE; + } + + + if ( pWtpStatus->Data[0] == PlatformReady && (pWtpStatus->Flags & 0x1) != MESSAGEPENDING) + { + break; + } + + } + + return IsOk; +} + + +int OpenUsbPort (struct CWtpComm *me) +{ + tfprintf(me->m_hLog,_T("\ntry to openUsbPort:%s....\n"),me->m_pLinuxUsb->DevName); + me->m_bXDB_BREAKPOINT_RETRY = TRUE; + _tcscpy(me->m_szDeviceName,me->m_pLinuxUsb->DevName); + int retry = 0; + system("echo ---begin open usb--- > /dev/kmsg"); +Retry: + retry++; + int retValue = BulkDevNonDrv_OpenDev(me->m_pLinuxUsb); + if(0 == retValue) + { +#if PRINTLOG + perror(_T("open")); +#endif + usleep(5000*100); + if(retrym_hLog,_T("\nopenUsbPort timeout\n")); + } + } + tfprintf(me->m_hLog,_T("\nopenUsbPort m_fdUsb = %s....\n"),me->m_pLinuxUsb->DevName); + return retValue; +} + + +BOOL CloseUsbPort(struct CWtpComm *me) +{ + //tfprintf(m_hLog,_T("\nCloseUsbPort....\n")); + if (me->m_pLinuxUsb->hDevHandle != 0) + BulkDevNonDrv_CloseDev(me->m_pLinuxUsb); +#if PRINTLOG + tprintf(_T("\nCloseUsbPort devName = %s....\n"),me->m_pLinuxUsb->DevName); +#endif + return TRUE; +} + + +void HandlePendingMessages(struct CWtpComm *me, WTPSTATUS *pWtpStatus ) +{ + // this is a bogus way to let the bootrom that uses a small packetsize + // have a little more time to process the command + + HandleTraceLog(me,_T("HandlePendingMessages CMD\n")); + + pWtpStatus->Status = ACK; + do + { + if ((pWtpStatus->Flags & 0x1 )== MESSAGEPENDING ) + { + GetTargetMessage (me,pWtpStatus); + HandleTraceLog(me,_T("HandlePendingMessages CMD\n")); + } + else + { + HandleTraceLog(me,_T("HandlePendingMessages break\n")); + break; + } + } + while( pWtpStatus->Status != ACK ); + + HandleTraceLog(me,_T("HandlePendingMessages return\n")); + +} + + +BOOL isFastDownload(struct CWtpComm *me,BOOL mode, BOOL value) //added to set/get the fast download mode. +{ + + if (mode) + me->m_bfastDownload = value; + else + return me->m_bfastDownload; + + return FDMODE; +} +BOOL isLastData(struct CWtpComm *me,BOOL mode, BOOL value) //added to set/get the last data condition. +{ + + if (mode) + me->m_blastData = value; + else + return me->m_blastData; + + return FDMODE; +} +BOOL WriteUSB(struct CWtpComm *me,WTPCOMMAND* pWtpCmd,size_t dwSize) +{ + HandleTraceLog(me,_T("WriteUSB\n")); + BOOL bRes = TRUE; + size_t dwBytes = -1; + int iMsgCnt = 0; + + if(me->m_ThreadExit==STOPFLAG) + { + tfprintf(me->m_hLog,_T("Thread is to be exit")); + return FALSE; + } + + if (me->m_pLinuxUsb->hDevHandle == -1) + { +#if PRINTLOG + tprintf(_T("\nError: device is not exist\n")); +#endif + return FALSE; + } +Retry: +#ifdef MACDOWNLOAD + int iVal = m_WtptpCommunicator.Write(pWtptpDev,pWtpCmd, dwSize); + if(iVal!=0) + { + fprintf(me->m_hLog, "Write USB failed\n"); + bRes = FALSE; + } +#else + dwBytes = BulkDevNonDrv_Write(me->m_pLinuxUsb,pWtpCmd,dwSize); + if(dwBytes<=0) + bRes = FALSE; +#endif + if (!bRes) + { + tfprintf(me->m_hLog,_T("\nError: write failed and return -1\n")); +#if PRINTLOG + printf(_T("\nError: write failed and return -1 iMsgCnt=%d\n"),iMsgCnt); +#endif + iMsgCnt++; + + usleep(200); + + if ( iMsgCnt == 10 ) + { +#if PRINTLOG + tprintf(_T("Error: Write failed with error %s.\n"),strerror(errno)); +#endif + return FALSE; + + } + + usleep(1000); + goto Retry; + } + else + { + HandleTraceLog(me,_T("WriteUSB dwBytes = %d\n"),dwBytes); + } + return bRes; +} + +BOOL WriteUSBWithNoRsp (struct CWtpComm *me,BYTE *pData,size_t dwSize) +{ + TCHAR Message[256] = {0}; + BOOL bRes = TRUE; + size_t dwBytes = -1; + int iMsgCnt = 0; + + if(me->m_ThreadExit==STOPFLAG) + { + tfprintf(me->m_hLog,_T("Thread is to be exit")); + return FALSE; + } + + if (me->m_pLinuxUsb->hDevHandle == -1) + { + sprintf (Message,_T(" Error: device is not exist!")); + tfprintf(me->m_hLog,_T("\n%s\n"),Message); + return FALSE; + } + + if(me->m_bDebugTrace) + { + sprintf (Message,_T("WriteUSBWithNoRsp dwSize is %d"),dwSize); + tfprintf(me->m_hLog,_T("\n%s\n"),Message); + tprintf(_T("\n%s\n"),Message); + } +Retry: + +#ifdef MACDOWNLOAD + int iVal = me->m_WtptpCommunicator.Write(pWtptpDev,pData, dwSize); + if(iVal!=0) + { + fprintf(me->m_hLog, "SelectImage Write USB failed\n"); + bRes = FALSE; + } +#else + dwBytes = BulkDevNonDrv_Write (me->m_pLinuxUsb,pData,dwSize); + if(dwBytes<=0) + bRes = FALSE; +#endif + + if (!bRes) + { + iMsgCnt++; + if(me->m_bDebugTrace) + { + tprintf(_T("Retry in WriteUSBWithNoRsp\n")); + } + if ( iMsgCnt == 20 ) + { +#ifdef PRINTLOG + tprintf(_T("Error: Write failed with error: %s,ErrorCode:%d.\n"),strerror(errno),errno); +#endif + fprintf(me->m_hLog,_T("Error: Write failed with error: %s,ErrorCode:%d.\n"),strerror(errno),errno); + + return FALSE; + + } + + usleep(1000); + goto Retry; + } + return bRes; +} + +BOOL ReadUSB (struct CWtpComm *me,WTPSTATUS *pWtpStatus,size_t dwSize) +{ + + BOOL bRes = TRUE; + size_t dwBytes = -1; + int iMsgCnt = 0; + + if(me->m_ThreadExit==STOPFLAG) + { + tfprintf(me->m_hLog,_T("Thread is to be exit")); + return FALSE; + } + if (me->m_pLinuxUsb->hDevHandle == -1) + { +#if PRINTLOG + tprintf (_T(" Error: device is not exist!\n")); +#endif + tfprintf(me->m_hLog,_T("\n Error: device is not exist!\n")); + return FALSE; + } + memset(pWtpStatus,0,sizeof(WTPSTATUS)); +Retry: + +#ifdef MACDOWNLOAD + int ival = me->m_WtptpCommunicator.Read(pWtptpDev,pWtpStatus, dwSize); + if(ival!=0) + { + fprintf(me->m_hLog, "Read USB failed\n"); + bRes = FALSE; + } +#else + dwBytes = BulkDevNonDrv_Read(me->m_pLinuxUsb,pWtpStatus,dwSize,0); + if(dwBytes<=0) + bRes = FALSE; +#endif + if (!bRes) + { + iMsgCnt++; + + HandleTraceLog(me,_T("Retry in ReadUSB\n")); + + if(iMsgCnt == 10 ) + { + tfprintf(me->m_hLog,_T("Error: ReadUSB failed with error %s.errno = %d\n"),strerror(errno),errno); +#if PRINTLOG + tprintf(_T("Error: ReadUSB failed with error %s.errno = %d\n"),strerror(errno),errno); +#endif + return FALSE; + } + + usleep(1000); + goto Retry; + } + else + { + //tfprintf(m_hLog,_T("\nReadUSB dwBytes = %d\n"),dwBytes); + TCHAR m_szMessage[256]; + sprintf (m_szMessage,_T("\nBytesRead : %d pWtpStatus:%x %x %x %x %x %x %x"), + dwBytes, + pWtpStatus->CMD, + pWtpStatus->SEQ, + pWtpStatus->CID, + pWtpStatus->Status, + pWtpStatus->Flags, + pWtpStatus->DLEN, + pWtpStatus->Data[0]); + + // tfprintf (m_hLog,_T("\nReadUSB message%s\n"),m_szMessage); + HandleTraceLog(me,_T("\nReadUSB message%s\n"),m_szMessage); + if (dwBytes<1) + { + iMsgCnt++; + + HandleTraceLog(me,_T("Retry in ReadUSB for read bytes is 0\n")); + + if(iMsgCnt == 10 ) + { +#if PRINTLOG + tprintf(_T("Error: ReadUSB failed for no data got.\n"),strerror(errno)); +#endif + return FALSE; + + } + + usleep(1000); + goto Retry; + } + } + + return bRes; +} +// features added to support upload 2010-12-28 +BOOL GetProtocolVersion (struct CWtpComm *me, PROTOCOL_VERSION* pTargetProtocolVersion ) +{ + WTPSTATUS WtpStatus = {0}; + BOOL IsOk = TRUE, EnableMessages = TRUE, bFoundChar = TRUE; + me->m_iSequence = 0x00; + WTPCOMMAND WtpCmd = {PROTOCOLVERSION,me->m_iSequence,0x00,0x00,htole32(0x00000000)}; + DWORD BytesRead = 0, StatusLength = 0; + + + //set to defaults + memset( &WtpStatus, 0, sizeof(WTPSTATUS) ); + HandlePendingMessages(me, &WtpStatus ); + + if(me->m_bDebugTrace) + { +#if PRINTLOG + tprintf(_T("GetProtocolVersion....\n")); +#endif + } + IsOk = WriteUSB (me,&WtpCmd,8); + + if(IsOk) + { + IsOk = FALSE; + IsOk = ReadUSB(me,&WtpStatus,6+sizeof(PROTOCOL_VERSION)); + + } + + if (WtpStatus.Status == NACK) + { + IsOk = FALSE; + tsprintf (me->m_szMessage,_T(" Error: GetProtocolVersion returned a NACK!")); + + } + else if (WtpStatus.Status == ACK) + { + if ( pTargetProtocolVersion ) + { + if ( WtpStatus.DLEN != sizeof(PROTOCOL_VERSION) ) + tfprintf(me->m_hLog,_T("nProtocolVersion returned LEN is not correct! LEN == %c\n"), WtpStatus.DLEN); + + memset( pTargetProtocolVersion, 0, sizeof(PROTOCOL_VERSION) ); + pTargetProtocolVersion->MajorVersion = WtpStatus.Data[0]; + pTargetProtocolVersion->MinorVersion = WtpStatus.Data[1]; + pTargetProtocolVersion->Build = Endian16ConvertLToB(&me->MyConvertLT2B,*((short*)&WtpStatus.Data[2])) ; + + tfprintf(me->m_hLog,_T("\nProtocolVersion: %d"), pTargetProtocolVersion->MajorVersion); + tfprintf(me->m_hLog,_T(".%d"), pTargetProtocolVersion->MinorVersion); + tfprintf(me->m_hLog,_T(".%d\n"), pTargetProtocolVersion->Build); + fflush(me->m_hLog); + if(me->m_bDebugTrace) + { + tprintf(_T("\nProtocolVersion: %d"), pTargetProtocolVersion->MajorVersion); + tprintf(_T(".%d"), pTargetProtocolVersion->MinorVersion); + tprintf(_T(".%d\n"), pTargetProtocolVersion->Build); + } + } + } + else + { + //Do nothing! + } + + HandlePendingMessages(me, &WtpStatus ); + + return IsOk; +} + + +BOOL GetParameters (struct CWtpComm *me, TARGET_PARAMS* pTargetParams ) +{ + WTPSTATUS WtpStatus = {0}; + BOOL IsOk = TRUE, EnableMessages = TRUE, bFoundChar = TRUE; + me->m_iSequence = 0x00; + WTPCOMMAND WtpCmd = {GETPARAMETERS,me->m_iSequence,0x00,0x00,htole32(0x00000000)}; + DWORD BytesRead = 0, StatusLength = 0; + + + HandlePendingMessages(me, &WtpStatus ); + if(me->m_bDebugTrace) + { + tprintf(_T("GetParameters....\n")); + } + if (!WriteUSB (me,&WtpCmd,8)) + { + IsOk = FALSE; + } + if(IsOk) + { + IsOk = FALSE; + IsOk = ReadUSB(me,&WtpStatus,6+sizeof(TARGET_PARAMS)); + + } + + if (WtpStatus.Status == NACK) + { + IsOk = FALSE; + tfprintf(me->m_hLog,_T(" Error: GetParameters returned a NACK!")); + fflush( me->m_hLog); + } + else if (WtpStatus.Status == ACK) + { + if ( WtpStatus.DLEN != 16 ) + { + tfprintf(me->m_hLog,_T("GetParameters returned LEN is not correct! LEN == %c\n"), WtpStatus.DLEN); + } + + + tfprintf(me->m_hLog, _T("\nBuffer Size: %d"), Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[0]))); + tfprintf(me->m_hLog, _T("\nRsvd1: %d"), Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[4]))); + tfprintf(me->m_hLog, _T("\nRsvd2: %d"), Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[8]))); + tfprintf(me->m_hLog, _T("\nRsvd3: %d\n"), Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[12]))); + fflush( me->m_hLog); + pTargetParams->BufferSize = Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[0])); + pTargetParams->Rsvd1 = Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[4])); + pTargetParams->Rsvd2 = Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[8])); + pTargetParams->Rsvd3 = Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[12])); + + if(me->m_bDebugTrace) + { + tprintf(_T("\nBuffer Size: %d"), Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[0]))); + tprintf(_T("\nRsvd1: %d"), Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[4]))); + tprintf(_T("\nRsvd2: %d"), Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[8]))); + tprintf(_T("\nRsvd3: %d\n"), Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)(&WtpStatus.Data[12]))); + } + } + else + { + //Do nothing! + } + + HandlePendingMessages(me, &WtpStatus ); + + return IsOk; + +} + + +BOOL UploadDataHeader (struct CWtpComm *me, UPLOAD_DATA_PARAMS* pUploadDataParams ) +{ + WTPSTATUS WtpStatus = {0}; + BOOL IsOk = TRUE, EnableMessages = TRUE, bFoundChar = TRUE; + me->m_iSequence = 0x00; + unsigned int i = 0; + WTPCOMMAND WtpCmd = {UPLOADDATAHEADER,me->m_iSequence,0x00,0x00,htole32(sizeof(UPLOAD_DATA_PARAMS))}; + DWORD BytesRead = 0, StatusLength = 0; + + // put upload parameters in + memcpy( WtpCmd.Data, pUploadDataParams, sizeof(UPLOAD_DATA_PARAMS) ); + + HandlePendingMessages(me, &WtpStatus ); + + if(me->m_bDebugTrace) + { + tprintf(_T("UploadDataHeader....\n")); + } + + if (!WriteUSB (me,&WtpCmd,8+sizeof(UPLOAD_DATA_PARAMS))) + { + IsOk = FALSE; + } + if(IsOk) + { + IsOk = FALSE; + IsOk = ReadUSB(me,&WtpStatus,6); + + } + + if (WtpStatus.Status == NACK) + { + IsOk = FALSE; + // tsprintf (m_szMessage,); + tfprintf(me->m_hLog, _T(" Error: UploadDataHeader returned a NACK!")); + if(WtpStatus.DLEN > 0) + { + tfprintf(me->m_hLog, _T("\nErrorCode in UploadData Header: %x\n"), Endian32ConvertLToB(&me->MyConvertLT2B,*(unsigned int*)&WtpStatus.Data[0])); +#if PRINTLOG + for (i = 0; i < MAXERRORCODES; i++) + { + if (WTPTPErrorCodes[i].ErrorCode == WtpStatus.Data[0]) + { +#ifndef COMPRESSDATA + tprintf(_T("Code: %s\n"), WTPTPErrorCodes[i].Description); +#endif + tprintf(_T("0x%x\n"), WtpStatus.Data[0]); + } + } +#endif + } + + } + fflush( me->m_hLog); + HandlePendingMessages(me, &WtpStatus ); + + return IsOk; +} + +BOOL UploadData(struct CWtpComm *me, PBYTE pData, unsigned int Length , WTPSTATUS* pWtpStatus) +{ + + BOOL IsOk = TRUE, EnableMessages = TRUE, bFoundChar = TRUE; + me->m_iSequence = 0x00; + WTPCOMMAND WtpCmd = {UPLOADDATA,me->m_iSequence,0x00,0x00,htole32(0x00000000)}; + DWORD StatusLength = Length; + + unsigned int i = 0; + + HandlePendingMessages(me, pWtpStatus ); + + if (!WriteUSBWithNoRsp (me,(PBYTE)&WtpCmd,8)) + { + IsOk = FALSE; + } + if(IsOk) + { + IsOk = FALSE; + IsOk = ReadUSB(me,pWtpStatus, 6+StatusLength); + + } + + if (pWtpStatus->Status == NACK) + { + IsOk = FALSE; + //tsprintf (m_szMessage,); + tfprintf(me->m_hLog,_T("Error: Data returned a NACK!")); + + } + else + { + // copy data back to data buffer + // exclude the 6 bytes used for the wtpstatus at the head of the packet + memcpy( pData, pWtpStatus->Data, StatusLength ); + HandlePendingMessages(me, pWtpStatus); + } + + fflush( me->m_hLog); + return IsOk; +} +void SetLogFile(struct CWtpComm *me,FILE *hLog) {me->m_hLog = hLog;} +FILE * GetLogFile(struct CWtpComm *me) {return me->m_hLog;} +void SetExitHandle(struct CWtpComm *me,int ThreadExit) {me->m_ThreadExit = ThreadExit;} +BOOL GetWTPTPFlag(struct CWtpComm *me){return me->m_bIsNonNewWTPTP;} +void SetWTPTPFlag(struct CWtpComm *me,BOOL IsNonNewWTPTP){me->m_bIsNonNewWTPTP = IsNonNewWTPTP;} +void SetLinuxDev(struct CWtpComm *me,USB_HANDLE* pLinuxDev) { me->m_pLinuxUsb = pLinuxDev;} +USB_HANDLE* GetLinuxDev(struct CWtpComm *me) { return me->m_pLinuxUsb ;} + diff --git a/fbfdownloader/src/WTPCOMMCLASS.h b/fbfdownloader/src/WTPCOMMCLASS.h new file mode 100644 index 00000000..fe7469ad --- /dev/null +++ b/fbfdownloader/src/WTPCOMMCLASS.h @@ -0,0 +1,113 @@ +// WTPCOMMCLASS.h: interface for the CWtpComm class. +// +////////////////////////////////////////////////////////////////////// + +#if !defined(AFX_WTPCOMMCLASS_H__EFECE7AD_7863_476C_A5A5_65A1D728610A__INCLUDED_) +#define AFX_WTPCOMMCLASS_H__EFECE7AD_7863_476C_A5A5_65A1D728610A__INCLUDED_ + +#if _MSC_VER > 1000 +#pragma once +#endif // _MSC_VER > 1000 +#include +#include "define.h" +#include "WTPdef.h" +#include "ParaDefine.h" +#include "ConvetEdian.h" +#include "ApplicationINI.h" +#include "BulkDevNonDrv_Linux.h" + +static const PROTOCOL_VERSION TARGET_PROTOCOL_VERSION = {0x01, 0x01, 0x0000}; + +struct CWtpComm +{ + /*void GetCustomizePreambleCmd(pWTPTPREAMBLECOMMAND pCustCmd);*/ + struct CConvertLT2B MyConvertLT2B; + + + + + + USB_HANDLE * m_pLinuxUsb; + int m_PortType; + int m_iPortNumber; + BYTE m_iSequence; + size_t m_BytesWritten, m_BytesRead; + long int m_liTimeout; + TCHAR m_szMessage[1024]; + BOOL m_bVerbose; + BOOL m_bLogFile; + BOOL m_bMsg; + volatile int m_ThreadExit; + MESSAGE_MODES MessageMode; + BOOL m_bBaudRateSet; + TCHAR m_szInterfaceName[256]; + TCHAR m_szDeviceName[256]; + BOOL m_bInterfaceSpecified; + unsigned int m_uiPacketSize; + BOOL m_bXDB_BREAKPOINT_RETRY; + //pWTPTPREAMBLECOMMAND m_pCustPreambleCmd; + FILE *m_hLog; + BOOL m_bfastDownload ; + BOOL m_blastData ; + BOOL m_bIsNonNewWTPTP; + BOOL m_bDebugTrace; + EDeviceType m_DeviceType; + ePlatForm m_PlatformType; + +}; +void NewCWtpComm (struct CWtpComm *me); +void SetPortType (struct CWtpComm *me,int iSelect); +int GetPortType (struct CWtpComm *me); +void SetUsbPortTimeout (struct CWtpComm *me,long int lTimeout); +int OpenUsbPort (struct CWtpComm *me); +BOOL CloseUsbPort (struct CWtpComm *me); +BOOL SendPreamble (struct CWtpComm *me,BOOL bIsCustPreamble); +BOOL GetVersion (struct CWtpComm *me,WTPSTATUS *pWtpStatus); +BOOL GetBadBlockInfo(struct CWtpComm *me,WTPSTATUS *pWtpStatus); +BOOL GetImageCrc(struct CWtpComm *me,WTPSTATUS *pWtpStatus); +BOOL SelectImage (struct CWtpComm *me,UINT32 *pImageType); +BOOL VerifyImage (struct CWtpComm *me,BYTE AckOrNack); +BOOL DataHeader (struct CWtpComm *me,unsigned int uiRemainingData,WTPSTATUS *pWtpStatus, BOOL bFastDownload); +BOOL Data (struct CWtpComm *me,PBYTE pData,UINT32 Length); +BOOL DebugBoot (struct CWtpComm *me,PBYTE pFlashType); +BOOL Done (struct CWtpComm *me); +BOOL Disconnect (struct CWtpComm *me,WTPSTATUS *pWtpStatus); +BOOL PublicKey (struct CWtpComm *me); +BOOL Password (struct CWtpComm *me,WTPSTATUS *pWtpStatus); +BOOL SignedPassword (struct CWtpComm *me); +BOOL GetWtpMessage (struct CWtpComm *me,WTPSTATUS *pWtpStatus); +BOOL GetTargetMessage (struct CWtpComm *me,WTPSTATUS *pWtpStatus); +void SetFlashType (struct CWtpComm *me,BYTE FlashCode); +BYTE GetFlashType (struct CWtpComm *me); +BOOL OtpView (struct CWtpComm *me); +void SetLogFileMode (struct CWtpComm *me,BOOL bLogOnOff); +void SetInterfaceName (struct CWtpComm *me,TCHAR* pInterfaceName); +void SetMessageMode (struct CWtpComm *me,MESSAGE_MODES MessageModeOnOff); +BOOL WaitForHostReply (struct CWtpComm *me,WTPSTATUS *pWtpStatus,int nCharsRead,int nTotalChars); +void SetPacketSize(struct CWtpComm *me, unsigned short uiSize ); +unsigned short GetPacketSize(struct CWtpComm *me); +void SetLogFile(struct CWtpComm *me,FILE *hLog); +FILE * GetLogFile(struct CWtpComm *me); +int GetUSBPort(struct CWtpComm *me); +void SetExitHandle(struct CWtpComm *me,int ThreadExit); +BOOL GetWTPTPFlag(struct CWtpComm *me); +void SetWTPTPFlag(struct CWtpComm *me,BOOL IsNonNewWTPTP); +void HandlePendingMessages(struct CWtpComm *me,WTPSTATUS *pWtpStatus); +BOOL isLastData(struct CWtpComm *me,BOOL mode, BOOL value); //added to set/get the last data condition. +BOOL WriteUSB (struct CWtpComm *me,WTPCOMMAND* pWtpCmd,size_t dwSize); +BOOL WriteUSBWithNoRsp (struct CWtpComm *me,BYTE *pData,size_t dwSize); +BOOL ReadUSB (struct CWtpComm *me,WTPSTATUS *WtpStatus,size_t dwSize); +BOOL isFastDownload(struct CWtpComm *me,BOOL mode, BOOL value); +// features added to support upload +BOOL GetProtocolVersion (struct CWtpComm *me, PROTOCOL_VERSION* pTargetProtocolVersion ); +BOOL GetParameters (struct CWtpComm *me, TARGET_PARAMS* pTargetParams ); +BOOL UploadDataHeader (struct CWtpComm *me, UPLOAD_DATA_PARAMS* pUploadDataParams ); +BOOL UploadData(struct CWtpComm *me, PBYTE pData, unsigned int Length , WTPSTATUS* pWtpStatus); +BOOL HandleUploadDataPacket(struct CWtpComm *me, PBYTE pData, unsigned int Length ); +void HandleTraceLog(struct CWtpComm *me,const TCHAR* format,...); +void CWtpCommSetBootDeviceType(struct CWtpComm *me,EDeviceType eType); +void SetPlatformType(struct CWtpComm *me,ePlatForm ePlatformType); +void SetLinuxDev(struct CWtpComm *me,USB_HANDLE* pLinuxDev); +USB_HANDLE* GetLinuxDev(struct CWtpComm *me); + +#endif // !defined(AFX_WTPCOMMCLASS_H__EFECE7AD_7863_476C_A5A5_65A1D728610A__INCLUDED_) diff --git a/fbfdownloader/src/WTPIOCTL.h b/fbfdownloader/src/WTPIOCTL.h new file mode 100644 index 00000000..7411b340 --- /dev/null +++ b/fbfdownloader/src/WTPIOCTL.h @@ -0,0 +1,134 @@ +/************************************************************************** +** +** (C) Copyright December 2006 Marvell International Ltd. +** +** All Rights Reserved. +** +** This software file (the "File") is distributed by Marvell International +** Ltd. under the terms of the GNU General Public License Version 2, June +** 1991 (the "License"). You may use, redistribute and/or modify this File +** in accordance with the terms and conditions of the License, a copy of +** which is available along with the File in the license.txt file or by +** writing to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, +** Boston, MA 02111-1307 or on the worldwide web at +** http://www.gnu.org/licenses/gpl.txt. +** +** THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE +** IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR +** PURPOSE ARE EXPRESSLY DISCLAIMED. The License provides additional +** details about this warranty disclaimer. +** +** FILENAME: WTPIOCTL.H +** +** PURPOSE: This contains the IoCtl code(s) and other external interfaces +** supported in BOOT. +** +** IMPORTANT NOTE: +** Because this header file includes the DEFINE_GUID declaration +** it should only be included in the WTPUSBLIB dll. This is +** because the GUID for the USB driver should only be advertised +** once to the operating system. +** +** Environment: +** Kernel mode only +** +******************************************************************************/ + +#pragma warning (disable : 4005) + +#ifndef WTPIOCTLDEF +#define WTPIOCTLDEF + +#define CTL_CODE(DeviceType, Function, Method, Access) ( ((DeviceType) << 16) | \ + ((Access) << 14) | \ + ((Function) << 2) | \ + (Method) ) + +#define FILE_ANY_ACCESS 0 +#define FILE_DEVICE_UNKNOWN 0x00000022 + +#define METHOD_BUFFERED 0 +#define METHOD_IN_DIRECT 1 +#define METHOD_OUT_DIRECT 2 +#define METHOD_NEITHER 3 + +#define BOOT_IOCTL_INDEX 0xDF0 // specific ioctls based from here. + +#define BOOT_IOCTL_METHOD_NEITHER(function) CTL_CODE(FILE_DEVICE_UNKNOWN, \ + (BOOT_IOCTL_INDEX + function), \ + METHOD_NEITHER, FILE_ANY_ACCESS) + +#define BOOT_IOCTL_METHOD_IN_DIRECT(function) CTL_CODE(FILE_DEVICE_UNKNOWN, \ + (BOOT_IOCTL_INDEX + function), \ + METHOD_IN_DIRECT, FILE_ANY_ACCESS) + +#define BOOT_IOCTL_METHOD_OUT_DIRECT(function) CTL_CODE(FILE_DEVICE_UNKNOWN, \ + (BOOT_IOCTL_INDEX + function), \ + METHOD_OUT_DIRECT, FILE_ANY_ACCESS) + +#define BOOT_IOCTL_METHOD_BUFFERED(function) CTL_CODE(FILE_DEVICE_UNKNOWN, \ + (BOOT_IOCTL_INDEX + function), \ + METHOD_BUFFERED, FILE_ANY_ACCESS) + +#define IOCTL_BOOT_PREAMBLE BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_GETVERSION BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_PUBLICKEYXMIT BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_SEEDPASSWORDRECEIVE BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_SIGNEDPASSWORDXMIT BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_SELECTIMAGE BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_JUMPADDRESS BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_IMAGEDATAXMIT BOOT_IOCTL_METHOD_BUFFERED(8) +#define IOCTL_BOOT_VERIFYIMAGE BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_DATAHEADER BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_OTPVIEW BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_DEBUGBOOT BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_DISCONNECT BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_DONE BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_MESSAGE BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_PROTOCOLVERSION BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_GETPARAMETERS BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_UPLOADDATAHEADER BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_UPLOADDATA BOOT_IOCTL_METHOD_BUFFERED(9) +#define IOCTL_BOOT_SEND BOOT_IOCTL_METHOD_BUFFERED(14) +#define IOCTL_BOOT_RECEIVE BOOT_IOCTL_METHOD_BUFFERED(15) + +typedef unsigned long ULONG; + +#pragma pack(push,1) + typedef struct _BOOTROM_COMMAND { + UCHAR Command; + UCHAR Sequence; + USHORT Length; + UCHAR Data[3996]; + } BOOTROM_COMMAND, *PBOOTROM_COMMAND; + + typedef struct _BOOTROM_PREAMBLE { + UCHAR Data[4]; + } BOOTROM_PREAMBLE, *PBOOTROM_PREAMBLE; + + typedef struct _BOOTROM_SENDPUBLICKEY { + UCHAR Command; + UCHAR Sequence; + USHORT Length; + ULONG KeyLength; // can be 16, 32, or 64. units is 4 byte words + UCHAR PublicKeyAndModulus[4 * 64 + 4 * 64]; // pub key & mod are same leng + // mod immediately follows actual pub key with no padding + } BOOTROM_SENDPUBLICKEY, *PBOOTROM_SENDPUBLICKEY; + + typedef struct _BOOTROM_SENDENCRYPTEDSIGNATURE { + UCHAR Command; + UCHAR Sequence; + USHORT Length; + UCHAR EncryptedSignature[4 * 64]; + } BOOTROM_SENDENCRYPTEDSIGNATURE, *PBOOTROM_SENDENCRYPTEDSIGNATURE; + + typedef union _BOOTROM_PACKET { + BOOTROM_PREAMBLE Preamble; + BOOTROM_COMMAND Command; + BOOTROM_SENDPUBLICKEY SendPublicKey; + BOOTROM_SENDENCRYPTEDSIGNATURE SendEncryptedSignature; + } BOOTROM_PACKET, *PBOOTROM_PACKET; +#pragma pack(pop) + + +#endif diff --git a/fbfdownloader/src/WTPdef.h b/fbfdownloader/src/WTPdef.h new file mode 100644 index 00000000..ca19a48c --- /dev/null +++ b/fbfdownloader/src/WTPdef.h @@ -0,0 +1,186 @@ +/************************************************************************** +** +** (C) Copyright December 2006 Marvell International Ltd. +** +** All Rights Reserved. +** +** This software file (the "File") is distributed by Marvell International +** Ltd. under the terms of the GNU General Public License Version 2, June +** 1991 (the "License"). You may use, redistribute and/or modify this File +** in accordance with the terms and conditions of the License, a copy of +** which is available along with the File in the license.txt file or by +** writing to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, +** Boston, MA 02111-1307 or on the worldwide web at +** http://www.gnu.org/licenses/gpl.txt. +** +** THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE +** IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR +** PURPOSE ARE EXPRESSLY DISCLAIMED. The License provides additional +** details about this warranty disclaimer. +** +** FILENAME: WTPdef.h +** +** PURPOSE: Definition file for the WTPTP software tools.. +** +******************************************************************************/ + +#ifndef WTPDEF_H // Only make declarations once. +#define WTPDEF_H +#include "kstring.h" +#include "./Macrodef.h" + +#define DATALENGTH 0x4000 +//#define RETURNDATALENGTH 0x1FFA // Update for upload data size is 0x2000 +#define MESSAGELENGTH 256 + + +#ifndef __cplusplus + #define ISMSGPORT FALSE // Use this to enable port handshaking errors for debugging. +#endif + + + + +#define USB 0 +#define SERIALPORT 1 +#define UNKNOWNPORT -1 + +#define ACK 0 +#define NACK 1 +#define MESSAGEPENDING 1 +#define MESSAGESTRING 0 +#define MESSAGEERRORCODE 1 + +// Image ID definitions +#define TIMH 0x54494D48 +#define DKBI 0x444B4249 +#define OBMI 0x4F424D49 +#define FBFI 0x46424649 +#define FBFD 0x46424644 +#define PART 0x50415254 +#define TZII 0x545A4949 +#define WTMI 0x57544D49 + + +#define NOFASTDOWNLOAD 'N' //added for fast download proj--used to turn off fast download +#define GET 0 //added for fast download proj--flag for fast download. +#define SET 1 //added for fast download proj--flag for fast download. +#define FDMODE 1 //dummy/default value when getting the value for fast download. + +typedef enum +{ + DISABLED = 1, // Standard WTPTP download + MSG_ONLY = 2, //Turn on message mode(listen for msgs forever) + MSG_AND_DOWNLOAD = 3 //Msg mode and WTPTP download +} MESSAGE_MODES; + +struct stImageFile +{ + UINT32 nFileType; + const char* strImageFile; +}; +#define __stI_free(x) +KLIST_INIT(stifl,struct stImageFile,__stI_free) + +struct stImageFileByDDR +{ + klist_t(stifl) *ImageFileList; + kstring_t sDDRVendorID; + kstring_t sFlashInfo; +}; +static void New_stImageFileByDDR(struct stImageFileByDDR * me) +{ + me->ImageFileList = kl_init(stifl); +} +static void Del_stImageFileByDDR(struct stImageFileByDDR * me) +{ + if (me == NULL) return; + printf("kl_destroy(stifl, me->ImageFileList);\n"); + kl_destroy(stifl, me->ImageFileList); + free( me); +} + + +#define __stID_free(x) Del_stImageFileByDDR(kl_val(x)) + +KLIST_INIT(stifdl,struct stImageFileByDDR*,__stID_free) + +typedef klist_t(stifl)* t_ImageFileList; +typedef kliter_t(stifl)* t_ImageFileListIter; +typedef kliter_t(stifl)* t_ImageFileListConstIter; + +typedef klist_t(stifdl)* t_ImageFileByDDRList; +typedef kliter_t(stifdl)* t_ImageFileByDDRIter; + +// Protocol command definitions +#define PREAMBLE 0x00 +#define PUBLICKEY 0x24 +#define PASSWORD 0x28 +#define SIGNEDPASSWORD 0x25 +#define GETVERSION 0x20 +#define SELECTIMAGE 0x26 +#define VERIFYIMAGE 0x27 +#define DATAHEADER 0x2A +#define DATA 0x22 +#define MESSAGE 0x2B +#define OTPVIEW 0x2C +#define DEBUGBOOT 0x2D +#define IMEIBIND 0x2E +#define IMEIDATA 0x2F +#define DONE 0x30 +#define DISCONNECT 0x31 +#define UPLOADDATAHEADER 0x32 +#define UPLOADDATA 0x33 +#define PROTOCOLVERSION 0x34 +#define GETPARAMETERS 0x35 +#define GETBADBLOCK 0x37 +#define GETIMAGECRC 0x38 +#define UNKNOWNCOMMAND 0xFF + + +#define UPLOAD_WITH_SPAREAREA 1 +#define UPLOAD_WITHOUT_SPAREAREA 0 + + + +#pragma pack(push,1) +typedef struct +{ + BYTE CMD; + BYTE SEQ; + BYTE CID; + BYTE Flags; + UINT32 LEN; + BYTE Data[DATALENGTH]; +} WTPCOMMAND; + + +typedef struct +{ + BYTE CMD; + BYTE SEQ; + BYTE CID; + BYTE Status; + BYTE Flags; + BYTE DLEN; + BYTE Data[DATALENGTH]; +} WTPSTATUS; + +typedef struct +{ + BYTE MajorVersion; + BYTE MinorVersion; + short Build; +} PROTOCOL_VERSION; + +typedef struct +{ + unsigned int BufferSize; + unsigned int Rsvd1; + unsigned int Rsvd2; + unsigned int Rsvd3; +} TARGET_PARAMS; + +#pragma pack(pop) + +#endif diff --git a/fbfdownloader/src/WtptpDownLoad.c b/fbfdownloader/src/WtptpDownLoad.c new file mode 100644 index 00000000..1b8c7ee5 --- /dev/null +++ b/fbfdownloader/src/WtptpDownLoad.c @@ -0,0 +1,21 @@ + +#include "WtptpDownLoad.h" +#include "WtptpDownloader.h" + +struct CWtptpDownLoad gWtptpDownload; +BOOL InitializeBL(PInstanceParams pInstParam) +{ + return WtptpDownLoad_InitializeBL(&gWtptpDownload,pInstParam); + +} +#if 0 +BOOL InitializeBLEx(PInstanceParams pInstParam,const TCHAR* pszBlfFile,const TCHAR* pszFBFTimfile, const TCHAR* pszFBFFile) +{ + return WtptpDownLoad_InitializeBLEx(&gWtptpDownload,pInstParam,pszBlfFile,pszFBFTimfile,pszFBFFile); + +} +#endif +BOOL TerminateBL() +{ + return WtptpDownLoad_TerminateBL(&gWtptpDownload); +} diff --git a/fbfdownloader/src/WtptpDownLoad.h b/fbfdownloader/src/WtptpDownLoad.h new file mode 100644 index 00000000..0d200e92 --- /dev/null +++ b/fbfdownloader/src/WtptpDownLoad.h @@ -0,0 +1,7 @@ +#include "ParaDefine.h" +extern struct CWtptpDownLoad gWtptpDownload; + + +BOOL InitializeBL(PInstanceParams pInstParam); +//BOOL InitializeBLEx(PInstanceParams pInstParam,const TCHAR* pszBlfFile,const TCHAR* pszFBFTimfile, const TCHAR* pszFBFFile); +BOOL TerminateBL(); diff --git a/fbfdownloader/src/WtptpDownloader.c b/fbfdownloader/src/WtptpDownloader.c new file mode 100644 index 00000000..efc93bd9 --- /dev/null +++ b/fbfdownloader/src/WtptpDownloader.c @@ -0,0 +1,3386 @@ +// WtptpDownLoad.cpp : Defines the entry point for the DLL application. +// + +#include "Macrodef.h" +#ifdef PCIEDOWNLOAD +#include "Parser.h" +#ifdef LS_PCIEDOWNLOAD +#include "asm/types.h" //for lightsurfuring +#endif +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ErrorCode.h" +#include "WtptpDownloader.h" +#include "WTPCOMMCLASS.h" +#include "Tim.h" +//#include "listdefine.h" +#include "Typedef.h" +#include "WTPdef.h" +#include "ParaDefine.h" +#include "CommonFun.h" + +/****************************************************/ +#define UEVENT_BUFFER_SIZE 2048 +#define UNIT_GB 0X40000000 +static BOOL isFastDownloadSwtchSet = 1; + +struct CBinFileWtp gBinFileWtp; + +char g_LogPath[255] = {0}; + + +const struct stFlatformBootLoaderInfo gstFlatformBLInfoSet[] = { + {PLAT_ULC2, ULC2_BOOTLOADER_DATE, ULC2_BOOTLOADER_PROCESSOR, ULC2_BOOTLOADER_VERSION}, + {PLAT_HELAN4, HELAN4_BOOTLOADER_DATE, HELAN4_BOOTLOADER_PROCESSOR, HELAN4_BOOTLOADER_VERSION}, + {PLAT_HELAN3, HELAN3_BOOTLOADER_DATE, HELAN3_BOOTLOADER_PROCESSOR, HELAN3_BOOTLOADER_VERSION}, + {PLAT_ULC1, ULC1_BOOTLOADER_DATE, ULC1_BOOTLOADER_PROCESSOR, ULC1_BOOTLOADER_VERSION}, + {PLAT_NEZHA3, NEZHA3_BOOTLOADER_DATE, NEZHA3_BOOTLOADER_PROCESSOR, NEZHA3_BOOTLOADER_VERSION}, + {PLAT_EDEN_A0, EDENA0_BOOTLOADER_DATE, EDENA0_BOOTLOADER_PROCESSOR, EDENA0_BOOTLOADER_VERSION}, + {PLAT_HELAN2, HELAN2_BOOTLOADER_DATE, HELAN2_BOOTLOADER_PROCESSOR, HELAN2_BOOTLOADER_VERSION}, + /*{PLAT_NEZHA2, NEZHA2_BOOTLOADER_DATE, NEZHA2_BOOTLOADER_PROCESSOR, NEZHA2_BOOTLOADER_VERSION},*/ + {PLAT_EDEN, EDEN_BOOTLOADER_DATE, EDEN_BOOTLOADER_PROCESSOR, EDEN_BOOTLOADER_VERSION}, + {PLAT_HELANLTE, HELAN_BOOTLOADER_DATE, HELAN_BOOTLOADER_PROCESSOR, HELAN_BOOTLOADER_VERSION}, + {PLAT_HELAN, HELAN_BOOTLOADER_DATE, HELAN_BOOTLOADER_PROCESSOR, HELAN_BOOTLOADER_VERSION}, + {PLAT_EMEI, EMEI_BOOTLOADER_DATE, EMEI_BOOTLOADER_PROCESSOR, EMEI_BOOTLOADER_VERSION}, + {PLAT_NEVO_OTA, NEVO_BOOTLOADER_DATE, NEVO_BOOTLOADER_PROCESSOR, NEVO_BOOTLOADER_VERSION}, + {PLAT_NEVO, NEVO_BOOTLOADER_DATE, NEVO_BOOTLOADER_PROCESSOR, NEVO_BOOTLOADER_VERSION}, + {PLAT_MMP3, MMP3_BOOTLOADER_DATE, MMP3_BOOTLOADER_PROCESSOR, MMP3_BOOTLOADER_VERSION}, + {PLAT_PXA92x, PXA92X_BOOTLOADER_DATE, PXA92X_BOOTLOADER_PROCESSOR, PXA92X_BOOTLOADER_VERSION}, + {PLAT_MMP2, MMP2_BOOTLOADER_DATE, MMP2_BOOTLOADER_PROCESSOR, MMP2_BOOTLOADER_VERSION}, + {PLAT_WUKONG, WKNG_BOOTLOADER_DATE, WKNG_BOOTLOADER_PROCESSOR, WKNG_BOOTLOADER_VERSION} +}; + +void NewCWtptpDownLoad (struct CWtptpDownLoad *me) +{ + NewCConvertLT2B(&me->MyConvertLT2B); + me->m_nBurningSpeed = 0; + me->m_bTerminateDownload = FALSE; + if (me->m_WtptpDeviceList) + kl_destroy(pdevl, me->m_WtptpDeviceList); + me->m_WtptpDeviceList = kl_init(pdevl); +#if DEBUG_MODE + me->m_bDebugTrace = TRUE; +#else + me->m_bDebugTrace = FALSE; +#endif + if (me->m_DisplayInfoList) + kl_destroy(pdisl, me->m_DisplayInfoList); + me->m_DisplayInfoList = kl_init(pdisl); + if (me->m_lBootRomImageWithDDRList) + kl_destroy(stifdl,me->m_lBootRomImageWithDDRList); + me->m_lBootRomImageWithDDRList = kl_init(stifdl); + if (me->m_lBootLoaderImageWithDDRList) + kl_destroy(stifdl, me->m_lBootLoaderImageWithDDRList); + me->m_lBootLoaderImageWithDDRList = kl_init(stifdl); + if (me->m_lJtagEnabledImageWithDDRList) + kl_destroy(stifdl, me->m_lJtagEnabledImageWithDDRList); + me->m_lJtagEnabledImageWithDDRList = kl_init(stifdl); + me->m_bOnlyOBMDownload = FALSE; + me->m_bTerminateUSBDetect = FALSE; + me->m_bSingleDownload = FALSE; + me->m_bIsLittleEndian = FALSE; + me->m_uTotalDDRTypeNum = 0; + me->m_uTotalFlashTypeNum = 0; + IsLittleEndian(&me->MyConvertLT2B); + +} +void DelCWtptpDownLoad (struct CWtptpDownLoad *me) +{ + printf("DelCWtptpDownLoad\n"); + for(t_DisplayInfoIter iter = kl_begin(me->m_DisplayInfoList); iter!=kl_end(me->m_DisplayInfoList); iter = kl_next(iter)) + { + free( kl_val(iter)); + } + kl_destroy(pdisl,me->m_DisplayInfoList); + kl_destroy(pdevl, me->m_WtptpDeviceList); + kl_destroy(stifdl,me->m_lBootRomImageWithDDRList); + kl_destroy(stifdl,me->m_lBootLoaderImageWithDDRList); + kl_destroy(stifdl,me->m_lJtagEnabledImageWithDDRList); + + /*for(t_DeviceIter iter = m_WtptpDeviceList.begin(); iter != m_WtptpDeviceList.end(); ++iter) + { + delete (*iter)->pWtpComm; + delete *iter; + } + m_WtptpDeviceList.clear();*/ + pthread_mutex_destroy(&me->DeviceList_mutex); + pthread_mutex_destroy(&me->Quit_mutex); + pthread_mutex_destroy(&me->callback_mutex); +} + + +BOOL WtptpDownLoad_RemoveEntryList(struct CWtptpDownLoad *me,PDEVICE pDev) +{ + t_DeviceIter iter; + for( t_DeviceIter iter = kl_begin(me->m_WtptpDeviceList); iter != kl_end(me->m_WtptpDeviceList); iter = kl_next(iter)) + { + if(pDev==kl_val(iter)) + { + CloseUsbPort(pDev->pWtpComm); + kl_erase(pdevl, me->m_WtptpDeviceList, &iter); + if (pDev->pWtpComm != NULL) + { + free( pDev->pWtpComm); + pDev->pWtpComm = NULL; + } + if (pDev != NULL) + { + free( pDev); + pDev = NULL; + } + break; + } + } + return TRUE; +} + +PVOID WtptpDownLoad_BootRomIOThread(PVOID Arg) +{ + + BOOL bSuccess = FALSE; + PDOWNLOADTARGET pTarget = (PDOWNLOADTARGET)Arg; + PDEVICE pDev = pTarget->pDev ; + + tfprintf (pDev->hLog,_T("\nEnter BootRomIOThread\n")); + static int ActiveBootRomDev; + + BOOL bReport = TRUE; + + tfprintf (pDev->hLog,_T("\nEnter BootRom Thread\n")); + fflush(pDev->hLog); + bSuccess = WtptpDownLoad_WTPTPDownLoad(pTarget->pWtptpDownload,pDev); + + + if (bSuccess) + { + tfprintf (pDev->hLog,_T("\nDownLoad Images to BootRom Completed\n")); + } + else + { + pDev->kProState =kProcAborting; + WtptpDownLoad_AddDisplayInfoDevice(pTarget->pWtptpDownload,pDev); + WtptpDownLoad_Report(pTarget->pWtptpDownload); + tfprintf (pDev->hLog,_T("\nAbnormal Termination in BootRom\n")); + tprintf(_T("Download failed in BootRom thread\n")); + } + + tfprintf (pDev->hLog,_T("\nExit BootRom Thread\n")); + fflush(pDev->hLog); + + if (pDev->hLog != NULL ) + { + fclose (pDev->hLog); + pDev->hLog = NULL; + } + + for(int i =0; ipWtptpDownload->m_nBootRomDevNum%32; i++) + { + if(pDev->ThreadId == pTarget->pWtptpDownload->BootRomTypeThread[i]) + { + pTarget->pWtptpDownload->BootRomTypeThread[i] = 0; + break; + } + } + + if(!bSuccess) + { + + time_t now; + char strtemp[255]; + time(&now); + struct tm *timenow; + timenow = localtime(&now); + char szfailedlogname[256] = {0}; + sprintf(szfailedlogname,"%s/%d_%d_%d_%d_%d_%d_failed_wtp.log", pTarget->pWtptpDownload->m_szSWDPath,timenow->tm_year+1900,timenow->tm_mon+1,timenow->tm_mday,timenow->tm_hour,timenow->tm_min,timenow->tm_sec); + tprintf(_T("failelog name is %s\n"),szfailedlogname); + if(taccess(pDev->LogFileName,0)==0) + { + tprintf(_T("rename is %s\n"),pDev->LogFileName); + rename(pDev->LogFileName,szfailedlogname); + } + } + + WtptpDownLoad_RemoveDisplayInfoDevice(pTarget->pWtptpDownload,pDev); + pthread_mutex_lock(&pTarget->pWtptpDownload->DeviceList_mutex); + pTarget->pWtptpDownload->m_nBootRomDevNum--; + WtptpDownLoad_RemoveEntryList(pTarget->pWtptpDownload,pDev); + pthread_mutex_unlock(&pTarget->pWtptpDownload->DeviceList_mutex); + + free( pTarget); + pTarget = NULL; + pthread_detach(pthread_self()); + + return NULL; +} + + + + + +PVOID WtptpDownLoad_BootLoaderIOThread(PVOID Arg) +{ +#if PRINTLOG + tprintf(_T("Enter into BootLoaderIOThread\n")); +#endif + PDOWNLOADTARGET pTarget = (PDOWNLOADTARGET)Arg; + PDEVICE pDev = pTarget->pDev ; + + tfprintf (pDev->hLog,_T("\nEnter into BootLoader Thread\n")); + fflush(pDev->hLog); + BOOL bSuccess = FALSE; + if(pTarget->pWtptpDownload->m_bSingleDownload) + { + pTarget->pWtptpDownload->m_bTerminateUSBDetect = TRUE; + } + bSuccess = WtptpDownLoad_WTPTPDownLoad(pTarget->pWtptpDownload,pDev); + + if(bSuccess) + { + pDev->kProState =kProcCompleted; + WtptpDownLoad_AddDisplayInfoDevice( pTarget->pWtptpDownload,pDev); + WtptpDownLoad_Report(pTarget->pWtptpDownload); + + } + else + { + pDev->kProState =kProcAborting; + WtptpDownLoad_AddDisplayInfoDevice( pTarget->pWtptpDownload,pDev); + WtptpDownLoad_Report(pTarget->pWtptpDownload); + tfprintf (pDev->hLog,_T("\nAbnormal Termination in BootLoader\n")); + + time_t now; + char strtemp[255]; + time(&now); + struct tm *timenow; + timenow = localtime(&now); + char szfailedlogname[256] = {0}; + sprintf(szfailedlogname,"%s/%d_%d_%d_%d_%d_%d_failed_wtp.log", pTarget->pWtptpDownload->m_szSWDPath,timenow->tm_year+1900,timenow->tm_mon+1,timenow->tm_mday,timenow->tm_hour,timenow->tm_min,timenow->tm_sec); + tprintf(_T("failelog name is %s\n"),szfailedlogname); + if(taccess(pDev->LogFileName,0)==0) + { + tprintf(_T("rename is %s\n"),pDev->LogFileName); + rename(pDev->LogFileName,szfailedlogname); + } + } + + tfprintf (pDev->hLog,_T("\nBootLoader Thread Completed!\n")); + fflush(pDev->hLog); + + if (pDev->hLog != NULL ) + { + fclose (pDev->hLog); + pDev->hLog = NULL; +#if PRINTLOG + tprintf(_T("\nBootLoader Thread Completed A!\n")); +#endif + } + +#ifndef __ANDROID__ + WtptpDownLoad_RemoveDisplayInfoDevice(pTarget->pWtptpDownload,pDev); + pthread_mutex_lock(&pTarget->pWtptpDownload->DeviceList_mutex); + pTarget->pWtptpDownload->m_nBootLoaderDevNum--; + WtptpDownLoad_RemoveEntryList(pTarget->pWtptpDownload,pDev); + pthread_mutex_unlock(&pTarget->pWtptpDownload->DeviceList_mutex); +#endif +#if PRINTLOG + tprintf(_T("\nBootLoader Thread Completed B!\n")); +#endif + free( pTarget); + pTarget = NULL; +#if PRINTLOG + tprintf(_T("\nBootLoader Thread Completed C!\n")); +#endif + pthread_detach(pthread_self()); //detach thread to release memory resources for joinable thread +#if PRINTLOG + tprintf(_T("\nBootLoader Thread Completed E!\n")); +#endif + return NULL; + +} + + + +PVOID WtptpDownLoad_BootLoaderUploadThread(PVOID Arg) +{ + tprintf(_T("Enter BootLoaderIOThread\n")); + static int ActiveUploadBootloader = 0; + PDOWNLOADTARGET pTarget = (PDOWNLOADTARGET)Arg; + PDEVICE pDev = pTarget->pDev ; + tfprintf (pDev->hLog,_T("\nEnter BootLoader Thread\n")); + fflush(pDev->hLog); + BOOL bSuccess = FALSE; + bSuccess = WtptpDownLoad_UploadDataFromTarget(pTarget->pWtptpDownload,pDev); + if(bSuccess) + { + pDev->kProState =kProcCompleted; + WtptpDownLoad_AddDisplayInfoDevice( pTarget->pWtptpDownload,pDev); + WtptpDownLoad_Report(pTarget->pWtptpDownload); + tfprintf (pDev->hLog,_T("\nBootLoader Upload Thread Completed!\n")); + } + else + { + pDev->kProState =kProcAborting; + WtptpDownLoad_AddDisplayInfoDevice( pTarget->pWtptpDownload,pDev); + WtptpDownLoad_Report(pTarget->pWtptpDownload); + + tfprintf (pDev->hLog,_T("\nAbnormal Termination in BootUpload\n")); + + } + + fflush(pDev->hLog); + if (pDev->hLog != NULL ) + { + fclose (pDev->hLog); + pDev->hLog = NULL; + + } + pthread_mutex_lock(&pTarget->pWtptpDownload->DeviceList_mutex); + pTarget->pWtptpDownload->m_nUploadDevNum--; + WtptpDownLoad_RemoveEntryList( pTarget->pWtptpDownload,pDev); + pthread_mutex_unlock(&pTarget->pWtptpDownload->DeviceList_mutex); + free( pTarget); + pTarget = NULL; + + tprintf (_T("\nBootLoader Upload Thread Completed!\n")); + pthread_detach(pthread_self()); + + return NULL; +} + + +void WtptpDownLoad_AddDisplayInfoDevice(struct CWtptpDownLoad *me,PDEVICE pDev) +{ + if(kl_size(pdisl,me->m_DisplayInfoList)==0) + { + PDISPLAYINFO pDevDisplayInfo = (PDISPLAYINFO)malloc(sizeof(DISPLAYINFO)); + memset(pDevDisplayInfo,0,sizeof(DISPLAYINFO)); + memcpy(pDevDisplayInfo->UsbDevName,pDev->UsbDevName,sizeof(pDev->UsbDevName)); + memcpy(pDevDisplayInfo->szCurrentMsg,pDev->szCurrentMsg,sizeof(pDev->szCurrentMsg)); + memcpy(&pDevDisplayInfo->szBadBlk,&pDev->DevBadBlk,sizeof(pDev->DevBadBlk)); + memcpy(&pDevDisplayInfo->szImageCrc,&pDev->DevImageCrc,sizeof(pDev->DevImageCrc)); + pDevDisplayInfo->kProState = pDev->kProState; + pDevDisplayInfo->npercent = pDev->npercent; + *kl_pushp(pdisl, me->m_DisplayInfoList) = pDevDisplayInfo; + } + else + { + BOOL bIsDeviceExist = FALSE; + t_DisplayInfoIter Iter = kl_begin(me->m_DisplayInfoList); + const char* sDeviceName, *stmp; + sDeviceName = pDev->UsbDevName; + while(Iter!=kl_end(me->m_DisplayInfoList)) + { + stmp = kl_val(Iter)->UsbDevName; + if(strstr(stmp,sDeviceName)!=NULL) + { + bIsDeviceExist = TRUE; + memcpy(kl_val(Iter)->UsbDevName,pDev->UsbDevName,sizeof(pDev->UsbDevName)); + memcpy(kl_val(Iter)->szCurrentMsg,pDev->szCurrentMsg,sizeof(pDev->szCurrentMsg)); + memcpy(&kl_val(Iter)->szBadBlk,&pDev->DevBadBlk,sizeof(pDev->DevBadBlk)); + memcpy(&kl_val(Iter)->szImageCrc,&pDev->DevImageCrc,sizeof(pDev->DevImageCrc)); + kl_val(Iter)->kProState = pDev->kProState; + kl_val(Iter)->npercent = pDev->npercent; + break; + } + Iter = kl_next(Iter); + } + + if(!bIsDeviceExist) + { + PDISPLAYINFO pDevDisplayInfo = (PDISPLAYINFO)malloc(sizeof(DISPLAYINFO)); + memset(pDevDisplayInfo,0,sizeof(DISPLAYINFO)); + memcpy(pDevDisplayInfo->UsbDevName,pDev->UsbDevName,sizeof(pDev->UsbDevName)); + memcpy(pDevDisplayInfo->szCurrentMsg,pDev->szCurrentMsg,sizeof(pDev->szCurrentMsg)); + memcpy(&pDevDisplayInfo->szBadBlk,&pDev->DevBadBlk,sizeof(pDev->DevBadBlk)); + memcpy(&pDevDisplayInfo->szImageCrc,&pDev->DevImageCrc,sizeof(pDev->DevImageCrc)); + pDevDisplayInfo->kProState = pDev->kProState; + pDevDisplayInfo->npercent = pDev->npercent; + *kl_pushp(pdisl,me->m_DisplayInfoList)=pDevDisplayInfo; + } + + } +} +void WtptpDownLoad_RemoveDisplayInfoDevice(struct CWtptpDownLoad *me,PDEVICE pDev) +{ + + if(kl_size(pdisl,me->m_DisplayInfoList)==0) + { + return; + } + else + { + t_DisplayInfoIter Iter = kl_begin(me->m_DisplayInfoList); + const char* sDeviceName,*stmp; + sDeviceName = pDev->UsbDevName; + while(Iter!=kl_end(me->m_DisplayInfoList)) + { + stmp = kl_val(Iter)->UsbDevName; + if(strstr(stmp,sDeviceName)!= NULL) + { + free( kl_val(Iter)); + kl_val(Iter) = NULL; + kl_erase(pdisl,me->m_DisplayInfoList,&Iter); + break; + } + Iter = kl_next(Iter); + } + } + +} + +void WtptpDownLoad_Report(struct CWtptpDownLoad *me) +{ + + t_DisplayInfoIter iter = kl_begin(me->m_DisplayInfoList); + while(iter!=kl_end(me->m_DisplayInfoList)) + { + NotifyStatus ProcInfo; + memset(&ProcInfo,0, sizeof(ProcInfo)); + My_strcpy(ProcInfo.pszUSBPortAddress,_tcslen(kl_val(iter)->UsbDevName)+1,kl_val(iter)->UsbDevName); + My_strcpy(ProcInfo.pszProcMsg,_tcslen(kl_val(iter)->szCurrentMsg)+1,kl_val(iter)->szCurrentMsg); + memcpy(&ProcInfo.lpBadBlk,&kl_val(iter)->szBadBlk,sizeof(BadBlockData)); + memcpy(&ProcInfo.lpImageCrc,&kl_val(iter)->szImageCrc,sizeof(ImageCRCInfo)); + ProcInfo.eProcState = kl_val(iter)->kProState; + ProcInfo.nDownloadedPercent = kl_val(iter)->npercent; + + if (me->m_lpInstParam->CallbackProc) + { + pthread_mutex_lock(&me->callback_mutex); + ((CALLBACKPROC)me->m_lpInstParam->CallbackProc)(&ProcInfo); + pthread_mutex_unlock(&me->callback_mutex); + } + iter = kl_next(iter); + } + + +} + +BOOL WtptpDownLoad_SetAndWaitForThreadExit(struct CWtptpDownLoad *me,PDEVICE pDev) +{ + //pthread_mutex_lock(&Device_mutex); + pDev->ThreadExit = STOPFLAG; + SetExitHandle(pDev->pWtpComm,1); + //pthread_mutex_unlock(&Device_mutex); + usleep(2000000); + WtptpDownLoad_RemoveEntryList(me,pDev); + + return TRUE; +} + +void WtptpDownLoad_WtptpOpenDevice(struct CWtptpDownLoad *me,struct CWtptpDownLoad *pWtptpDownLoad, USB_HANDLE *pLinuxUsb) +{ + PDEVICE pDev = (PDEVICE)malloc(sizeof(DEVICE)); + memset(pDev, 0, sizeof(DEVICE)); + struct CWtpComm *pWtpComm = (struct CWtpComm *)malloc(sizeof(struct CWtpComm)); + NewCWtpComm(pWtpComm); + pDev->pWtpComm = pWtpComm; +#if PRINTLOG + printf(_T("add DevName:%s\n"), pLinuxUsb->DevName); +#endif + char szBuffer[MAX_FILE_LENGTH]; + memset(szBuffer,0,sizeof(TCHAR)*MAX_FILE_LENGTH); + snprintf(szBuffer,sizeof(szBuffer),("echo ---add DevName:%s--- > /dev/kmsg"),pLinuxUsb->DevName); + system(szBuffer); + PUSB_HANDLE pUsb = (PUSB_HANDLE) malloc(sizeof(USB_HANDLE)); + NEW_USB_HANDLE(pUsb); + COPY_USB_HANDLE(pUsb, pLinuxUsb); + SetLinuxDev(pDev->pWtpComm,pUsb); + + sprintf(pDev->UsbDevName, _T("%s"), pLinuxUsb->DevName); + char sUSBName[128]; + strcpy(sUSBName, pLinuxUsb->DevName); + WtptpDownLoad_replace_all(sUSBName, _T("/"), _T("_")); + sprintf(pDev->LogFileName, _T("%s/wtp%s.log"), pWtptpDownLoad->m_szSWDPath, sUSBName); + #if PRINTLOG + printf(_T("LogFileName is:%s\n"), pDev->LogFileName); +#endif + if (WtptpDownLoad_OpenDevice(pWtptpDownLoad,pDev)) + { + pthread_mutex_lock(&pWtptpDownLoad->DeviceList_mutex); + *kl_pushp(pdevl,pWtptpDownLoad->m_WtptpDeviceList)=pDev; + pthread_mutex_unlock(&pWtptpDownLoad->DeviceList_mutex); + + pDev->kProState = kProcConnecting; + WtptpDownLoad_AddDisplayInfoDevice(pWtptpDownLoad,pDev); + WtptpDownLoad_Report(pWtptpDownLoad); +#if PRINTLOG + tprintf(_T("Open device successfully\n")); +#endif + fflush(stdout); + } + else + { + pDev->kProState = kProcAborting; + WtptpDownLoad_AddDisplayInfoDevice(pWtptpDownLoad,pDev); + WtptpDownLoad_Report(pWtptpDownLoad); + tprintf(_T("Open device failed\n")); + fflush(stdout); + free( pDev); + pDev = NULL; + } +} + +PVOID WtptpDownLoad_WtptpDeviceDetectThread(PVOID Arg) +{ + + struct CWtptpDownLoad* pWtptpDownLoad = (struct CWtptpDownLoad*)Arg; + PUSB_HANDLE hUSBDev[MAX_DEVNUM]; + + int hotplug_sock = WtptpDownLoad_init_hotplug_sock(); + int existing_num = BulkDevNonDrv_FindAllSupportedDevices(hUSBDev); + if (0 == existing_num) + { +#if PRINTLOG + tprintf(_T("Please plug your USB device\n")); +#endif + fflush(stdout); + } + else + { + for (int loops = 0; loops < existing_num; loops++) + { + WtptpDownLoad_WtptpOpenDevice(pWtptpDownLoad,pWtptpDownLoad,hUSBDev[loops]); + tprintf(_T("Open existing USB device number %d\n"), loops); + fflush(stdout); + free( hUSBDev[loops]); + } + } + + while (1) + { + pthread_mutex_lock(&(pWtptpDownLoad->Quit_mutex)); + if(pWtptpDownLoad->m_bTerminateDownload) + { +#if PRINTLOG + tprintf(_T("\nQuit from detect device.....\n")); +#endif + break; + } + pthread_mutex_unlock(&(pWtptpDownLoad->Quit_mutex)); + usleep(100); + + /* Netlink message buffer */ + TCHAR buf[UEVENT_BUFFER_SIZE * 2] = {0}; + int nLen = recv(hotplug_sock, &buf, sizeof(buf), 0); + //printf(_T("Recieve message is:%s\n"), buf); + USB_HANDLE *pLinuxUsb; + int bAdd = 0; + pLinuxUsb = (USB_HANDLE *)calloc(1, sizeof(USB_HANDLE)); + if ( BulkDevNonDrv_CheckDevForNetLink(pLinuxUsb, buf, nLen, &bAdd) ) + { + if ( 1 == bAdd ) + { + if(pWtptpDownLoad->m_bTerminateUSBDetect) + { + continue; //不检测插入的新设备,但是可以检测移除的设备 + } + system("echo ---bAdd=1--- > /dev/kmsg"); + WtptpDownLoad_WtptpOpenDevice(pWtptpDownLoad,pWtptpDownLoad, pLinuxUsb); + } + else + if (0 == bAdd) + { + const char* sCurrentRemoveDevice = pLinuxUsb->DevName; +#if PRINTLOG + printf(_T("remove DevName:%s\n"), pLinuxUsb->DevName); +#endif + system("echo ---remove DevName--- > /dev/kmsg"); + pthread_mutex_lock(&pWtptpDownLoad->DeviceList_mutex); + if(kl_size(pdevl,pWtptpDownLoad->m_WtptpDeviceList)>0) + { + t_DeviceIter iter = kl_begin(pWtptpDownLoad->m_WtptpDeviceList); + while(iter!=kl_end(pWtptpDownLoad->m_WtptpDeviceList)) + { + const char* strDev = GetLinuxDev((kl_val(iter))->pWtpComm)->DevName; + const char* strtmp = pLinuxUsb->DevName; + if(strstr(sCurrentRemoveDevice,strtmp)!= NULL) // it this device is removed , so will terminate thread + { + WtptpDownLoad_SetAndWaitForThreadExit(pWtptpDownLoad,kl_val(iter)); + break; + } + iter = kl_next(iter); + } + } + pthread_mutex_unlock(&pWtptpDownLoad->DeviceList_mutex); + } + } + + + free( pLinuxUsb); + } + close(hotplug_sock); //close socket. + pthread_detach(pthread_self()); + return NULL; +} + +int WtptpDownLoad_init_hotplug_sock() +{ + const int buffersize = 1024*16*16; + int ret; + + struct sockaddr_nl snl; +#ifdef __ANDROID__ + memset(&snl, 0, sizeof(struct sockaddr_nl)); +#else + bzero(&snl, sizeof(struct sockaddr_nl)); +#endif + snl.nl_family = AF_NETLINK; + snl.nl_pid = getpid(); + snl.nl_groups = 1; +#if PRINTLOG + tprintf(_T("init_hotplug_sock\n")); +#endif + fflush(stdout); + + //tprintf(_T("enter into init_hotplug_sock, snl.nl_pid = %d,snl.nl_groups = %d\n"),snl.nl_pid,snl.nl_groups); + + int s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); + if (s == -1) + { +#if PRINTLOG + perror(_T("socket")); +#endif + return -1; + } + //tprintf(_T("socket return %d\n"),s); + ret = setsockopt(s, SOL_SOCKET, SO_RCVBUF, &buffersize, sizeof(buffersize)); + if (ret < 0) + { +#if PRINTLOG + perror(_T("setsockopt")); +#endif + } + + ret = bind(s, (struct sockaddr *)&snl, sizeof(struct sockaddr_nl)); + + if (ret < 0) + { + tprintf(_T("bind return %d... , errno %d\n"),ret , errno); + printf("strerror: %s\n", strerror(errno)); + close(s); + return -1; + } + + //tprintf(_T("Please plug your USB device\n")); + fflush(stdout); + + return s; +} + + +void WtptpDownLoad_SetBootDeviceType(struct CWtptpDownLoad *me,PDEVICE pDev,EDeviceType eDevieBootType) +{ + CWtpCommSetBootDeviceType(pDev->pWtpComm,eDevieBootType); + pDev->nDevType = eDevieBootType; + if (kBootLoader == eDevieBootType) + { + strcpy(pDev->szCurrentMsg,"Open an BootLoader Device"); + tfprintf (pDev->hLog,_T("\nOpen an BootLoader Device\n")); + } + else + { + strcpy(pDev->szCurrentMsg,"Open an BootRom Device"); + tfprintf (pDev->hLog,_T("\nOpen an BootRom Device\n")); + } + fflush(pDev->hLog); + + pDev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + +} + + + +BOOL WtptpDownLoad_GetDeviceBootType(struct CWtptpDownLoad *me,PDEVICE pDev) +{ + IsLittleEndian(&me->MyConvertLT2B); +#if PRINTLOG + tprintf(_T("Getting type of Device.....\n")); +#endif + if(me->m_bDebugTrace) + { + tprintf(_T("Getting type of Device.....\n")); + } + + tfprintf (pDev->hLog,_T("\nGetting type of Device\n")); + pDev->nDevType = kNone; + + MESSAGE_MODES currentMessageMode=MSG_AND_DOWNLOAD; + SetMessageMode( pDev->pWtpComm,currentMessageMode); + + + if (!OpenUsbPort(pDev->pWtpComm)) + { + tfprintf (pDev->hLog,_T("\n Open Usb Port in GetDeviceBootType failed\n")); + return FALSE; + } + SetPortType(pDev->pWtpComm,0);//set usb port as default + + if( PLAT_HELAN ==me->m_ePlatformType) + { + sleep (1); + } + if (!SendPreamble(pDev->pWtpComm,me->m_bCustPreamble) ) + { + tprintf (_T("\nSendPreamble failed in GetDeviceBootType\n")); + return FALSE; + } + + tfprintf (pDev->hLog,_T("\n GetTargetMessage after sendpreamble\n")); + WTPSTATUS WtpStatus = {0x00, 0x00, 0x00, 0x00, 0x01, htole32(0x00)}; + if (currentMessageMode == MSG_AND_DOWNLOAD ) + { + WtpStatus.Status = ACK; + if(!GetTargetMessage(pDev->pWtpComm,&WtpStatus)) + { + tfprintf (pDev->hLog,_T("\n GetTargetMessage after sendpreamble failed\n")); + return FALSE; + } + WtpStatus.Flags = 0x1; + } + + tfprintf(pDev->hLog,_T("\nGetting Version...\n")); + WtpStatus.CMD = 0x0; + WtpStatus.SEQ = 0x0; + WtpStatus.CID = 0x0; + WtpStatus.Status= 0x0; + WtpStatus.Flags = 0x1; + WtpStatus.DLEN = 0x0; + fflush(pDev->hLog); + + if (!GetVersion(pDev->pWtpComm,&WtpStatus)) + { + tprintf (_T("\nGetting Version failed\n")); + return FALSE; + } + if(ACK != WtpStatus.Status) + { + CWtpCommSetBootDeviceType(pDev->pWtpComm,kNone); + pDev->nDevType = kNone; + tprintf(_T("Can't get response from Target when getting type of device\n")); + tfprintf (pDev->hLog,_T("\nUnknown Device\n")); + fflush(pDev->hLog); + return FALSE; + } + + + TCHAR Processor[24]; + TCHAR Version[24]; + TCHAR Date[24]; + memset(Processor, 0, 24); + memset(Version, 0, 24); + memset(Date, 0, 24); + + if(me->m_bDebugTrace) + { + tprintf(_T("\nVersion: %c%c%c%c\n"),WtpStatus.Data[3],WtpStatus.Data[2],WtpStatus.Data[1],WtpStatus.Data[0]); + tprintf(_T("\nDate: %08X\n"),le32toh(*(unsigned int *)&WtpStatus.Data[4])); + tprintf(_T("\nProcessor: %c%c%c%c\n"),WtpStatus.Data[11],WtpStatus.Data[10],WtpStatus.Data[9],WtpStatus.Data[8]); + + } + sprintf(Version,_T("%c%c%c%c"),WtpStatus.Data[3],WtpStatus.Data[2],WtpStatus.Data[1],WtpStatus.Data[0]); + sprintf(Date,_T("%02x%02x%02x%02x"),WtpStatus.Data[7],WtpStatus.Data[6],WtpStatus.Data[5],WtpStatus.Data[4]); + sprintf(Processor,_T("%c%c%c%c"),WtpStatus.Data[11],WtpStatus.Data[10],WtpStatus.Data[9],WtpStatus.Data[8]); + const char* strProcessor,*strVersion,*strDate; + strProcessor = Processor; + strVersion = Version; + strDate = Date; + tfprintf(pDev->hLog,_T("\nVersion: %c%c%c%c"),WtpStatus.Data[3],WtpStatus.Data[2],WtpStatus.Data[1],WtpStatus.Data[0]); + tfprintf(pDev->hLog,_T("\nDate: %08X"),le32toh(*(unsigned int *)&WtpStatus.Data[4])); + tfprintf(pDev->hLog,_T("\nProcessor: %c%c%c%c"),WtpStatus.Data[11],WtpStatus.Data[10],WtpStatus.Data[9],WtpStatus.Data[8]); + fflush(pDev->hLog); + + + + BOOL bObmSupportMutliDDR = FALSE; + BOOL bObmSupportMultiFlash = FALSE; + UINT32 uiEMMCSize = 0; + UINT32 uiDdrVendorId = 0; + UINT32 uiDdrUnitSize = 0; + TCHAR szDDRVendorID[20]; + memset(szDDRVendorID,0,sizeof(szDDRVendorID)); + //new OBM return DDR Vendor ID and DDR SIZE 8 bytes: 4 bytes for Vendor ID : ID01,ID02;DDR size : 0001,0002 the value is unit(512M) + if(20 == WtpStatus.DLEN) + { + tsprintf(szDDRVendorID,_T("0x%c%c"),WtpStatus.Data[13],WtpStatus.Data[12]); + uiDdrVendorId = Str2Uint32(szDDRVendorID); + uiDdrUnitSize = *(unsigned long *)&WtpStatus.Data[16]; + bObmSupportMutliDDR = TRUE; + } + else if (24 == WtpStatus.DLEN) + { + tsprintf(szDDRVendorID,_T("0x%c%c"),WtpStatus.Data[13],WtpStatus.Data[12]); + uiDdrVendorId = Str2Uint32(szDDRVendorID); + uiDdrUnitSize = *(unsigned long *)&WtpStatus.Data[16]; + uiEMMCSize = *(unsigned long *)&WtpStatus.Data[20]; + bObmSupportMutliDDR = TRUE; + bObmSupportMultiFlash = TRUE; + } + + EDeviceType eBootDeviceType = WtptpDownLoad_GetDeviceType(me,me->m_ePlatformType,strDate,strVersion,strProcessor); + if (kNone == eBootDeviceType) + { + strcpy(pDev->szCurrentMsg,"Unkown Device"); + pDev->kProState = kProcErrorCode; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + + tfprintf (pDev->hLog,_T("\nUnkown Device\n")); + fflush(pDev->hLog); + return FALSE; + } + + WtptpDownLoad_SetBootDeviceType(me,pDev, eBootDeviceType); + + + if(kBootLoader ==pDev->nDevType ) + { + if (FLASH_EMMC == me->m_FlashType) + { + if (me->m_uTotalDDRTypeNum>0 && !bObmSupportMutliDDR) + { + tfprintf (pDev->hLog,_T("Current OBM don't suppport multiple DDR feature, please update OBM.\n")); + return FALSE; + } + + if (me->m_uTotalFlashTypeNum>1 && !bObmSupportMultiFlash) + { + tfprintf (pDev->hLog,_T("Current OBM don't suppport multiple eMMC feature, please update OBM.\n")); + return FALSE; + } + + eDDREMMCMatchResult eError = WtptpDownLoad_HandleDownloadImagesByDDRIDandEMMCSize(me,uiDdrVendorId,uiDdrUnitSize,uiEMMCSize); + if(eError!=kMatchNoError) + { + + TCHAR szMessage[MAX_FILE_LENGTH]={0}; + if(kDDRMismatchError==eError) + { + tsnprintf(szMessage,MAX_FILE_LENGTH,_T("DDRType is not found , OBM read vendor DDR Pid 0x%x, can't find it in blf configure \n"),uiDdrVendorId<<8|uiDdrUnitSize); + } + else if(kEMMCMismatchError==eError) + { + tsnprintf(szMessage,MAX_FILE_LENGTH,_T("EMMC Size Type is not found , OBM read EMMC Size is %08X, can't find it in blf configure \n"),uiEMMCSize); + } + else + tsnprintf(szMessage,MAX_FILE_LENGTH,_T("InitialBL have issue\n")); + + tfprintf (pDev->hLog,szMessage); + return FALSE; + } + } + else if (FLASH_NAND == me->m_FlashType) + { + if (me->m_uTotalDDRTypeNum>0 && !bObmSupportMutliDDR) + { + tfprintf (pDev->hLog,_T("Current OBM don't suppport multiple DDR feature, please update OBM.\n")); + return FALSE; + } + + eDDREMMCMatchResult eError = WtptpDownLoad_HandleNandDLImgByDDRID(me,uiDdrVendorId,uiDdrUnitSize); + if(eError!=kMatchNoError) + { + TCHAR szMessage[MAX_FILE_LENGTH]={0}; + if(kDDRMismatchError==eError) + { + tsnprintf(szMessage,MAX_FILE_LENGTH,_T("DDRType is not found , OBM read vendor DDR Pid 0x%x, can't find it in blf configure \n"),uiDdrVendorId<<8|uiDdrUnitSize); + } + tfprintf (pDev->hLog,szMessage); + return FALSE; + } + } + else + { + t_ImageFileByDDRIter Iter = kl_begin(me->m_lBootLoaderImageWithDDRList); + me->m_plBootLoaderImageList = &((kl_val(Iter))->ImageFileList); + } + } + fflush(pDev->hLog); + return TRUE; +} + + +BOOL WtptpDownLoad_OpenDevice(struct CWtptpDownLoad *me,PDEVICE pDev) +{ + PDOWNLOADTARGET pTarget = (PDOWNLOADTARGET)malloc(sizeof(DOWNLOADTARGET)); + pTarget->pDev = pDev; + pTarget->pWtptpDownload = me; + if((pDev->hLog = _tfopen (pDev->LogFileName,_T("w"))) == NULL) + { + tprintf(_T("Create log file failed\n")); + return FALSE; + } + else + { + SetLogFile(pDev->pWtpComm,pDev->hLog); + } + SetPlatformType(pDev->pWtpComm,me->m_ePlatformType); + //Do upload only after detect a device if user want to do upload + if(me->m_bDumpFlash) + { + pDev->nDevType = kBootLoader; + pDev->SerialNo = me->m_nUploadDevNum; + int res= pthread_create(&me->UploadThread[me->m_nUploadDevNum%32], NULL,WtptpDownLoad_BootLoaderUploadThread , pTarget); + if(res!=0) + { +#if PRINTLOG + perror (_T("Thread creation failed\n")); +#endif + free( pTarget); + return FALSE; + } + else + { + pDev->ThreadId = me->UploadThread[me->m_nUploadDevNum%32]; + me->m_nUploadDevNum++; + + } + } + else + { + if(WtptpDownLoad_GetDeviceBootType(me,pDev)) + { +#if PRINTLOG + tprintf(_T("Get type of device successfully\n")); +#endif + tfprintf(pDev->hLog,_T("\nGet type of device successfully\n")); + fflush(pDev->hLog); + } + else + { + tprintf(_T("Get type of device failed\n")); + tfprintf(pDev->hLog,_T("\nGet type of device failed\n")); + fflush(pDev->hLog); + fclose(pDev->hLog); + free( pTarget); + return FALSE; + } + if(pDev->nDevType == kBootRom) + { + int res = pthread_create(&me->BootRomTypeThread[me->m_nBootRomDevNum%32], NULL,WtptpDownLoad_BootRomIOThread , pTarget); + if(res!=0) + { +#if PRINTLOG + perror (_T("Thread creation failed\n")); +#endif + fclose(pDev->hLog); + free( pTarget); + return FALSE; + } + else + { + pDev->ThreadId = me->BootRomTypeThread[me->m_nUploadDevNum%32]; + me->m_nBootRomDevNum++; + } + } + else if(pDev->nDevType == kBootLoader) + { +#if PRINTLOG + tprintf (_T("Thread creation BootLoaderTypeThread\n")); +#endif + int res = pthread_create(&me->BootLoaderTypeThread[me->m_nBootLoaderDevNum%32], NULL,WtptpDownLoad_BootLoaderIOThread , pTarget); + if(res!=0) + { +#if PRINTLOG + perror (_T("Thread creation failed\n")); +#endif + fclose(pDev->hLog); + free( pTarget); + return FALSE; + } + else + { + pDev->ThreadId = me->BootLoaderTypeThread[me->m_nBootLoaderDevNum%32]; + me->m_nBootLoaderDevNum++; + } + + } + } + + + return TRUE; + +} + + +BOOL WtptpDownLoad_DownloadImage(struct CWtptpDownLoad *me,PDEVICE pdev, int iFile,const t_ImageFileList* plImgFileList, UINT64 uiAllimgsize,UINT64 *uidownloadsize,int nImages,char* strDownloadImgName) +{ + if(pdev->ThreadExit == STOPFLAG) + { + pdev->kProState = kProcAborting; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + return FALSE; + } + _tcscpy(pdev->szCurrentMsg,_T("Begin DownloadImage...........")); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + fflush(pdev->hLog); + + WTPCOMMAND WtpCmd; + eProcessState eProcState; + MESSAGE_MODES currentMessageMode=MSG_AND_DOWNLOAD; + SetMessageMode(pdev->pWtpComm,currentMessageMode); + WTPSTATUS WtpStatus = {0x00, 0x00, 0x00, 0x00, 0x01, 0x00}; + UINT32 ImageType = 0; + BYTE IsImage = NACK; + unsigned int uiRemainingBytes = 0; + unsigned int uiBufferSize = 0; + TCHAR szFileName[MAX_PATH]; + memset(szFileName,0,MAX_PATH); + long lFileSize = 0,BytesRead; + FILE* hFile = NULL; + int i = 0; + + + if(iFile!=0) + { + tfprintf (pdev->hLog,_T("\nSending Preamble...\n")); + + if(me->m_bDebugTrace) + { + _tcscpy(pdev->szCurrentMsg,_T("Sending Preamble...")); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + } + + + if (!SendPreamble(pdev->pWtpComm,me->m_bCustPreamble)) + { + _tcscpy(pdev->szCurrentMsg,_T("SendPreamble can not get ACK...")); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + return FALSE; + } + + if (currentMessageMode == MSG_AND_DOWNLOAD ) + { + WtpStatus.Status = ACK; + GetTargetMessage(pdev->pWtpComm,&WtpStatus); + WtpStatus.Flags = 0x1; + } + tfprintf (pdev->hLog,_T("\nGetting Version...\n")); + + if(me->m_bDebugTrace) + { + _tcscpy(pdev->szCurrentMsg,_T("Getting Version...")); + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + } + + if (!GetVersion(pdev->pWtpComm,&WtpStatus)) + { + _tcscpy(pdev->szCurrentMsg,_T("GetVersion failed...")); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + return FALSE; + } + + + } + fflush(pdev->hLog); + if (!SelectImage(pdev->pWtpComm,&ImageType)) + { + _tcscpy(pdev->szCurrentMsg,_T("SelectImage failed...")); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + + return FALSE; + } + + + IsImage = WtptpDownLoad_AckWithImageName(me,ImageType,szFileName,plImgFileList); + strcpy(strDownloadImgName, szFileName); + if (!VerifyImage(pdev->pWtpComm,IsImage)) + { + _tcscpy(pdev->szCurrentMsg,_T("Verify image failed...")); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + + return FALSE; + + } + tsprintf(pdev->szCurrentMsg,_T("download file name is %s"),szFileName); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + + /*if ((hFile = _tfopen (szFileName,_T("rb"))) == NULL) + { + TCHAR szMessage[1024]; + sprintf(szMessage,_T("\nError: Can't open %s file!\n"),szFileName); + _tcscpy(pdev->szCurrentMsg,szMessage); + pdev->kProState = kProcDebugLog; + AddDisplayInfoDevice(pdev); + Report(); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + + return FALSE; + }*/ + if (!BinFileWtp_IsFileExist(&gBinFileWtp,szFileName)) + { + TCHAR szMessage[1024]; + sprintf(szMessage,_T("\nError: Can't open %s file!\n"),szFileName); + _tcscpy(pdev->szCurrentMsg,szMessage); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + + return FALSE; + + } + + //fseek (hFile,0L,SEEK_END); // Set position to EOF + //lFileSize = ftell (hFile); // Get position of file, thus the file size. + lFileSize = BinFileWtp_GetFileSize(&gBinFileWtp,szFileName); + + if ((ImageType == TIMH) || (ImageType == PART)) + { + //fseek (hFile,0L,SEEK_SET); // Set position to SOF + BinFileWtp_FseekBin(&gBinFileWtp,szFileName, 0L, SEEK_SET); + uiRemainingBytes = (unsigned int)lFileSize; + } + else + { + //fseek (hFile,4L,SEEK_SET); // Set position to SOF + BinFileWtp_FseekBin(&gBinFileWtp,szFileName, 4L, SEEK_SET); + uiRemainingBytes = (unsigned int)lFileSize - 4; + } + + if ((ImageType == FBFD) && me->m_bGetBadBlk && (!me->m_bEraseAllFlashOnly)) + { + /* + before download the FBF image, first judge the Bad block number + */ + _tcscpy(pdev->szCurrentMsg, _T("Getting Bad Blocks......")); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + + if (!GetBadBlockInfo(pdev->pWtpComm,&WtpStatus)) + { + _tcscpy(pdev->szCurrentMsg, _T("BBCError")); + pdev->kProState = kProcDownloading; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + + tfprintf (pdev->hLog,_T("Error: GetBadBlockInfo failed!\n")); + fflush(pdev->hLog); + //return FALSE; //Don't interrupt here, can do it in the mainfrm.cpp + } + else + { + pBadBlockData pFlashBadBlockData = (pBadBlockData)WtpStatus.Data; + memset(&pdev->DevBadBlk, 0, sizeof(BadBlockData)); + memcpy(&pdev->DevBadBlk,pFlashBadBlockData, sizeof(BadBlockData)); + _tcscpy(pdev->szCurrentMsg, _T("BadBlkNum")); + pdev->kProState = kProcDownloading; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + + tfprintf(pdev->hLog, _T("\nTotalBadBlocks: %d, Total Blocks: %d"),le32toh(pFlashBadBlockData->TotalBadBlocks),le32toh(pFlashBadBlockData->TotalBlocks)); + tfprintf(pdev->hLog, _T("\nImage ID: %s, bad Blocks: %d\n"),le32toh(pFlashBadBlockData->BadCount[0].ImageID),le32toh(pFlashBadBlockData->BadCount[0].BadCnt)); + + tfprintf (pdev->hLog,_T("GetBadBlockInfo OK!\n")); + fflush(pdev->hLog); + int u32TotalBlocks = le32toh(pdev->DevBadBlk.TotalBlocks); + int u32BadBlocks = le32toh(pdev->DevBadBlk.TotalBadBlocks); + if ( u32BadBlocks > (int)((double)(me->m_uFlashBadBlockRate*u32TotalBlocks)/(double)BADBLOCKRATE_BASE)) + { + _tcscpy(pdev->szCurrentMsg,_T("BadBlockRate is out of range!")); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + fflush(pdev->hLog); + return FALSE; + } + } + } + + pdev->kProState = kProcDownloading; + BOOL bFastDownload = FALSE; + //Helan2/Eden_A0 BootRom֧��fastdownload,����ƽֻ̨��BootLoader֧��fastdownload + if(kBootLoader == pdev->nDevType + || PLAT_EDEN_A0 == me->m_ePlatformType + || PLAT_HELAN2 == me->m_ePlatformType + || PLAT_ULC1 == me->m_ePlatformType + || PLAT_HELAN3 == me->m_ePlatformType + || PLAT_HELAN4== me->m_ePlatformType ) + { + bFastDownload = TRUE; + isFastDownload(pdev->pWtpComm,SET, TRUE); + } + else + { + isFastDownload(pdev->pWtpComm,SET, FALSE); + } + + if (!DataHeader(pdev->pWtpComm,uiRemainingBytes,&WtpStatus,bFastDownload)) + { + if (hFile != NULL) + fclose (hFile); + + tfprintf (pdev->hLog,_T("\nData header CMD failed\n")); + return FALSE; + } + else + { + for (int i = 0; i < (int)WtpStatus.DLEN; i++) + uiBufferSize |= WtpStatus.Data[i] << (8 * i); + } + + if(kBootRom== pdev->nDevType && PLAT_EDEN_A0 == me->m_ePlatformType) + { + usleep(100000); //100ms + } + + + tfprintf(pdev->hLog,_T("\nReturn flag in Dataheader CMD: %d,FDSwitch is %d,BufferSize is 0x%X\n"),WtpStatus.Flags,isFastDownloadSwtchSet,uiBufferSize); + fflush(pdev->hLog); + if(me->m_bDebugTrace) + { + TCHAR szMessage[1024]; + sprintf(szMessage,_T("Return flag in Dataheader CMD: %d,FDSwitch is %d"),WtpStatus.Flags,isFastDownloadSwtchSet); + _tcscpy(pdev->szCurrentMsg,szMessage); + pdev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s"),pdev->szCurrentMsg); + + } + if (WtpStatus.Flags & 0x4 && isFastDownloadSwtchSet) + { + fprintf (pdev->hLog,"\n*******NOTE:: Fast Download is NOW activated!\n"); + isFastDownload(pdev->pWtpComm,SET, TRUE); + fflush(pdev->hLog); + } + else + { + isFastDownload(pdev->pWtpComm,SET, FALSE); + fprintf (pdev->hLog,"\nFast Download is not activated\n"); + fflush(pdev->hLog); + } + + unsigned int uitotalsize=uiRemainingBytes; + double percentage; + unsigned int downloadbytes; + int loop =0; + while (uiRemainingBytes > 0) + { + + + if (! isFastDownload(pdev->pWtpComm,GET, FDMODE) && loop) + { + + if (!DataHeader(pdev->pWtpComm,uiRemainingBytes,&WtpStatus,FALSE) ) + { + tfprintf (pdev->hLog,_T("Error: WtpComm.DataHeader failed to receive an ACK!\n")); + if (hFile != NULL) fclose (hFile); + return FALSE; + } + else + { + for (int i = 0; i < (int)WtpStatus.DLEN; i++) + uiBufferSize |= WtpStatus.Data[i] << (8 * i); + } + + //workaround for eden a0 bootrom failed + if(kBootRom== pdev->nDevType && PLAT_EDEN_A0 == me->m_ePlatformType) + { + usleep(100000); //100ms + } + } + loop ++; + + + if(uiBufferSize > uiRemainingBytes) + { + uiBufferSize = uiRemainingBytes; + } + + + uiRemainingBytes -= uiBufferSize; // Calculate remaining bytes + if (isFastDownload(pdev->pWtpComm,GET, FDMODE)) + { + /* Code to see if last data */ + if(uiRemainingBytes == 0) + { + + tfprintf (pdev->hLog,_T("Last Data\n")); + isLastData(pdev->pWtpComm,SET, TRUE); + } + } + + + BYTE* pSendDataBuffer = (BYTE*)malloc(sizeof(BYTE)*uiBufferSize); + if(NULL == pSendDataBuffer) + { + tfprintf (pdev->hLog,_T("Molloc Memory failed in DownloadImage.\n")); + return FALSE; + } + + //BytesRead = fread (pSendDataBuffer,1,uiBufferSize,hFile); + BytesRead = BinFileWtp_ReadBinFile(&gBinFileWtp,pSendDataBuffer, 1, uiBufferSize, szFileName); + + + if ((BytesRead != (long)uiBufferSize)) + { + + if (hFile != NULL) fclose (hFile); + tfprintf (pdev->hLog,_T("Error:Read file failed!\n")); + free(pSendDataBuffer); + return FALSE; + } + + else + { + unsigned int totalSize = 0; + unsigned int mark = 0; + + // We do not split packets based on packetSize for FastDownload + + unsigned int packetSize = isFastDownload(pdev->pWtpComm,GET, FDMODE)? uiBufferSize : GetPacketSize(pdev->pWtpComm); + totalSize = uiBufferSize; + + if (totalSize > packetSize ) + { + do + { + if (!Data(pdev->pWtpComm,pSendDataBuffer + mark,packetSize) ) + { + if (hFile != NULL) fclose (hFile); + free(pSendDataBuffer); + return FALSE; + } + else + { + downloadbytes=uitotalsize-uiRemainingBytes; + percentage=(double)(*uidownloadsize+downloadbytes)/(double)uiAllimgsize; + double nPercent = percentage*100; + + pdev->kProState = kProcDownloading; + pdev->npercent = (int)nPercent; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + } + + mark += packetSize; + totalSize-=packetSize; + + if (totalSize <= packetSize) + packetSize = totalSize; + + } + while (totalSize > 0); + + } + else + { + if (!Data(pdev->pWtpComm,pSendDataBuffer,uiBufferSize)) + { + tfprintf (pdev->hLog,_T("\nData command failed\n")); + if (hFile != NULL) fclose (hFile); + free(pSendDataBuffer); + return FALSE; + } + else + { + downloadbytes=uitotalsize-uiRemainingBytes; + percentage=(double)(*uidownloadsize+downloadbytes)/(double)uiAllimgsize; + double nPercent = percentage*100; + + pdev->kProState = kProcDownloading; + pdev->npercent = (int)nPercent; + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + + } + } + } + + free(pSendDataBuffer); + pSendDataBuffer = NULL; + + } + tfprintf (pdev->hLog,_T("Download data finished\n")); + fflush(pdev->hLog); + if(me->m_bDebugTrace) + { + pdev->kProState = kProcDebugLog; + _tcscpy(pdev->szCurrentMsg,_T("Download data finished")); + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + + tfprintf (pdev->hLog,_T("%s"),pdev->szCurrentMsg); + + } + + Done(pdev->pWtpComm); + + if (isFastDownload(pdev->pWtpComm,GET, FDMODE)) + { + isLastData (pdev->pWtpComm,SET, FALSE); + } + + *uidownloadsize+=uitotalsize; + if (hFile != NULL) + fclose (hFile); + + + pdev->kProState = kProcDebugLog; + sprintf(pdev->szCurrentMsg,_T("Completed DownLoad file: %s"),szFileName); + WtptpDownLoad_AddDisplayInfoDevice(me,pdev); + WtptpDownLoad_Report(me); + tfprintf (pdev->hLog,_T("%s\n"),pdev->szCurrentMsg); + fflush(pdev->hLog); + + return TRUE; +} + + +BYTE WtptpDownLoad_AckWithImageName (struct CWtptpDownLoad *me,const UINT32 ImageType,TCHAR *szFileName,const t_ImageFileList* plImageList) +{ + BYTE IsImage = NACK; + + for (t_ImageFileListConstIter ite = kl_begin(*plImageList); ite != kl_end(*plImageList); ite = kl_next(ite)) + { + if (kl_val(ite).nFileType == ImageType) + { + IsImage = ACK; + _tcscpy (szFileName,kl_val(ite).strImageFile); + break; + } + } + + return IsImage; +} + + +#define __u32_free(x) +KLIST_INIT(u32,UINT32,__u32_free) + +BOOL WtptpDownLoad_ParseTim (struct CWtptpDownLoad *me,t_ImageFileByDDRList* ImageFileByDDRlist) +{ + t_ImageFileByDDRIter DDRDownloadIMGIter = kl_begin(*ImageFileByDDRlist); + klist_t(u32)* lImageIDList = kl_init(u32); + while(DDRDownloadIMGIter!= kl_end(*ImageFileByDDRlist)) + { + BOOL bFoundTim = FALSE; + const char* strTimFile; + for (t_ImageFileListIter ite = kl_begin(kl_val(DDRDownloadIMGIter)->ImageFileList); ite != kl_end(kl_val(DDRDownloadIMGIter)->ImageFileList); ite = kl_next(ite)) + { + FILE* fpFile = NULL; //= _tfopen(ite->strImageFile.c_str(), _T("rb")); + UINT32 dwTimId; + BinFileWtp_OpenBinFile(&gBinFileWtp,_T("rb")); + //fseek(fpFile,sizeof(UINT32),SEEK_SET); + BinFileWtp_FseekBin(&gBinFileWtp,kl_val(ite).strImageFile, sizeof(UINT32), SEEK_SET); + //fread(&dwTimId,sizeof(UINT32),1,fpFile); + BinFileWtp_ReadBinFile(&gBinFileWtp,&dwTimId,sizeof(UINT32) , 1,kl_val(ite).strImageFile); +#if PRINTLOG + printf("TIMH=0x%x dwTimId=0x%x le32toh(dwTimId)=0x%x\n",TIMH,dwTimId,le32toh(dwTimId)); +#endif + if (TIMH == le32toh(dwTimId)) + { + if (!bFoundTim) + { + bFoundTim = TRUE; + kl_val(ite).nFileType = TIMH; + strTimFile = kl_val(ite).strImageFile; + } + else + { + printf(_T("Find two Tim image in downloadImageList\n")); + kl_destroy(u32, lImageIDList); + return FALSE; + } + } + CloseFilePtr(&fpFile); + } + + if (!bFoundTim) + { + printf(_T("\nA Tim image file was not supplied! Exiting program.\n")); + kl_destroy(u32, lImageIDList); + return FALSE; + } + + + FILE *hTimFile = NULL; + CTIM TimHeader; + /*if ((hTimFile = _tfopen (strTimFile.c_str(), _T("rb"))) == NULL) + { + printf(_T("\n_tfopen failed to open Tim file: %s.\n"),strTimFile.c_str()); + return FALSE; + }*/ + if (!BinFileWtp_IsFileExist(&gBinFileWtp,strTimFile)) + { + printf(_T("\n_tfopen failed to open Tim file: %s.\n"),strTimFile); + kl_destroy(u32, lImageIDList); + return FALSE; + } + //fseek (hTimFile,0L,SEEK_SET); // Set position to SOF + BinFileWtp_FseekBin(&gBinFileWtp,strTimFile, 0L, SEEK_SET); + //fread (&TimHeader,sizeof(CTIM),1,hTimFile); + BinFileWtp_ReadBinFile(&gBinFileWtp,&TimHeader, sizeof(CTIM), 1, strTimFile); + int nImages = le32toh(TimHeader.NumImages); +#if PRINTLOG + printf(_T("Number of Images listed in TIM: %d\n"),nImages); +#endif + if (kl_size(stifl,kl_val(DDRDownloadIMGIter)->ImageFileList) != nImages) + { + printf(_T("Number of Images listed in TIM is %d, but provide image number is %d\n"),nImages,kl_size(stifl,kl_val(DDRDownloadIMGIter)->ImageFileList)); + kl_destroy(u32, lImageIDList); + return FALSE; + } + + + if(le32toh(TimHeader.VersionBind.Version) >= TIM_3_1_01 && le32toh(TimHeader.VersionBind.Version) < TIM_3_2_00) + { + IMAGE_INFO_3_1_0 ImageInfo; + for (int i = 0; i < nImages; i++) + { + //fread (&ImageInfo,sizeof(IMAGE_INFO_3_1_0),1,hTimFile); + BinFileWtp_ReadBinFile(&gBinFileWtp,&ImageInfo,sizeof(IMAGE_INFO_3_1_0),1,strTimFile); + *kl_pushp(u32,lImageIDList) = le32toh(ImageInfo.ImageID); + } + } + else if(le32toh(TimHeader.VersionBind.Version) >= TIM_3_2_00&& le32toh(TimHeader.VersionBind.Version) < TIM_3_4_00) + { + IMAGE_INFO_3_2_0 ImageInfo; + for (int i = 0; i < nImages; i++) + { + //fread (&ImageInfo,sizeof(IMAGE_INFO_3_2_0),1,hTimFile); + BinFileWtp_ReadBinFile(&gBinFileWtp,&ImageInfo,sizeof(IMAGE_INFO_3_2_0),1,strTimFile); + *kl_pushp(u32,lImageIDList) = le32toh(ImageInfo.ImageID); + } + } + else if(TIM_3_4_00 == le32toh(TimHeader.VersionBind.Version)) + { + IMAGE_INFO_3_4_0 ImageInfo; + for (int i = 0; i < nImages; i++) + { + //fread (&ImageInfo,sizeof(IMAGE_INFO_3_4_0),1,hTimFile); + BinFileWtp_ReadBinFile(&gBinFileWtp,&ImageInfo,sizeof(IMAGE_INFO_3_4_0),1,strTimFile); + *kl_pushp(u32,lImageIDList) = le32toh(ImageInfo.ImageID); + } + } + else if(TIM_3_5_00 == le32toh(TimHeader.VersionBind.Version)) + { + IMAGE_INFO_3_5_0 ImageInfo; + for (int i = 0; i < nImages; i++) + { + //fread (&ImageInfo,sizeof(IMAGE_INFO_3_5_0),1,hTimFile); + BinFileWtp_ReadBinFile(&gBinFileWtp,&ImageInfo,sizeof(IMAGE_INFO_3_5_0),1,strTimFile); + *kl_pushp(u32,lImageIDList) = le32toh(ImageInfo.ImageID); + } + } + else + { + printf(_T("\nTim Version is unknown:0X%X\n"),TimHeader.VersionBind.Version); + kl_destroy(u32, lImageIDList); + return FALSE; + } + + CloseFilePtr(&hTimFile); + + //���image Id�Ƿ������TIM�� + BOOL bFoundInTim = FALSE; + for (t_ImageFileListIter ite = kl_begin(kl_val(DDRDownloadIMGIter)->ImageFileList); ite != kl_end(kl_val(DDRDownloadIMGIter)->ImageFileList); ite = kl_next(ite)) + { + if (TIMH == kl_val(ite).nFileType) + { + continue; + } + + FILE* fpFile = NULL;//_tfopen(ite->strImageFile.c_str(), _T("rb")); + UINT32 dwImageId; + //fread(&dwImageId, sizeof(UINT32), 1, fpFile); + BinFileWtp_FseekBin(&gBinFileWtp,kl_val(ite).strImageFile,0L,SEEK_SET); + BinFileWtp_ReadBinFile(&gBinFileWtp,&dwImageId, sizeof(UINT32), 1, kl_val(ite).strImageFile); + dwImageId = le32toh(dwImageId); + + kl_val(ite).nFileType = dwImageId; + CloseFilePtr(&fpFile); + + BOOL bFound = FALSE; + for (kliter_t(u32) *imgIdIte = kl_begin(lImageIDList); imgIdIte != kl_end(lImageIDList);imgIdIte = kl_next(imgIdIte)) + { + if (kl_val(imgIdIte) == dwImageId) + { + bFound = TRUE; + } + } + + if (!bFound) + { + printf(_T("Tim don't contain ImageId 0X%X, imageFile:%s"), dwImageId,kl_val(ite).strImageFile); + kl_destroy(u32, lImageIDList); + return FALSE; + } + } + + //���TIM�а�����image�Ƿ���� + for (kliter_t(u32) * ite = kl_begin(lImageIDList); ite != kl_end(lImageIDList); ite = kl_next(ite)) + { + BOOL bFound = FALSE; + for (t_ImageFileListIter imgFileListIte = kl_begin(kl_val(DDRDownloadIMGIter)->ImageFileList);\ + imgFileListIte != kl_end(kl_val(DDRDownloadIMGIter)->ImageFileList);\ + imgFileListIte = kl_next(imgFileListIte)) + { + if (kl_val(ite) == kl_val(imgFileListIte).nFileType) + { + bFound = TRUE; + } + } + + if (!bFound) + { + printf(_T("Tim contains imageId 0X%X, but the image file don't exist."),*ite); + kl_destroy(u32, lImageIDList); + return FALSE; + } + } + DDRDownloadIMGIter = kl_next(DDRDownloadIMGIter); + } + kl_destroy(u32, lImageIDList); + return TRUE; +} + + +BOOL WtptpDownLoad_UploadDataFromTarget(struct CWtptpDownLoad *me,PDEVICE pDev) +{ + if(pDev->ThreadExit==STOPFLAG) + { + printf(_T("Thread is to be exit")); + return FALSE; + } + + _tcscpy(pDev->szCurrentMsg,_T("Enter into UploadDataFromTarget.....")); + pDev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + tfprintf (pDev->hLog,_T("%s"),pDev->szCurrentMsg); + + MESSAGE_MODES currentMessageMode = DISABLED; + WTPSTATUS WtpStatus = {0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; + isFastDownload (pDev->pWtpComm,SET, TRUE); + tfprintf (pDev->hLog,_T("Enter Upload Data\n")); + eProcessState eProcState; + long uiAllimgsize=0; + long uiUploadsize=0; + SetPacketSize(pDev->pWtpComm,USBPACKETSIZE); + int retryAttempts = 3; + tfprintf (pDev->hLog,_T("\nBegin OpenUsbPort\n")); + fflush(pDev->hLog); + if (!OpenUsbPort (pDev->pWtpComm)) + { + _tcscpy(pDev->szCurrentMsg,_T("Can not open USB.....")); + pDev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + tfprintf (pDev->hLog,_T("%s"),pDev->szCurrentMsg); + + return FALSE; + } + else + SetPortType(pDev->pWtpComm,0);//set usb port as default + + _tcscpy(pDev->szCurrentMsg,_T("Waiting for Uploading data...")); + pDev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + + if(me->m_bCustPreamble) + { + tprintf (_T("\nCustomize Preamble Mode\n")); + } + else + { + tprintf (_T("\nOriginal Preamble Mode\n")); + } + + + t_UpLoadDataSpecIter iter; + iter = kl_begin(*me->m_lpUpLoadDataSpecList); + UPLOAD_DATA_SPEC* pUploadSpec = NULL; + while ( iter != kl_end(*me->m_lpUpLoadDataSpecList) ) + { + + if (!SendPreamble(pDev->pWtpComm,me->m_bCustPreamble)) + { + return FALSE; + } + else + { + + PROTOCOL_VERSION TargetProtocolVersion; + memset( &TargetProtocolVersion, 0, sizeof(TargetProtocolVersion) ); + if ( GetProtocolVersion (pDev->pWtpComm, &TargetProtocolVersion ) ) + { + if ( TargetProtocolVersion.MajorVersion >= TARGET_PROTOCOL_VERSION.MajorVersion + && TargetProtocolVersion.MinorVersion >= TARGET_PROTOCOL_VERSION.MinorVersion + && TargetProtocolVersion.Build >= TARGET_PROTOCOL_VERSION.Build ) + { + TARGET_PARAMS TargetParams; + if (GetParameters(pDev->pWtpComm, &TargetParams ) ) + { + + pUploadSpec = kl_val(iter); + UINT32 OriginalUploadBytes = pUploadSpec->m_Params.DataSize; + + tprintf (_T("\n")); + tprintf (_T("\n")); + tprintf (_T("Uploading:\n")); + tprintf (_T("Type: %d\n"), kl_val(iter)->m_Params.Type); + tprintf (_T("SubType: %d\n"), kl_val(iter)->m_Params.SubType ); + tprintf (_T("Partition: %d\n"), kl_val(iter)->m_Params.Partition ); + if(FLASH_EMMC==me->m_FlashType) + { + tprintf (_T("Offset: %d\n"), (kl_val(iter)->m_Params.Offset*512)); + } + else + { + tprintf (_T("Offset: %d\n"), (kl_val(iter)->m_Params.Offset)); + } + tprintf (_T("DataSize: %d\n"), kl_val(iter)->m_Params.DataSize); + tprintf (_T("Upload Save file name is: %s\n"), kl_val(iter)->strOutputFileName.s); + tprintf (_T("ResetUE: %d\n"), (kl_val(iter)->m_Params.ResetUE)); + tprintf (_T("ResetTimeDelay: %d\n"), kl_val(iter)->m_Params.ResetTimeDelay); + tprintf (_T("\n")); + tprintf (_T("\n")); + tfprintf (pDev->hLog,_T("Uploading:\n")); + tfprintf (pDev->hLog,_T("Type: %d\n"), kl_val(iter)->m_Params.Type); + tfprintf (pDev->hLog,_T("SubType: %d\n"), kl_val(iter)->m_Params.SubType ); + tfprintf (pDev->hLog,_T("Partition: %d\n"), kl_val(iter)->m_Params.Partition ); + if(FLASH_EMMC==me->m_FlashType) + { + tfprintf (pDev->hLog,_T("Offset: %d\n"), (kl_val(iter)->m_Params.Offset*512)); + } + else + { + tfprintf (pDev->hLog,_T("Offset: %d\n"), (kl_val(iter)->m_Params.Offset)); + } + tfprintf (pDev->hLog,_T("DataSize: %d\n"), kl_val(iter)->m_Params.DataSize); + tfprintf (pDev->hLog,_T("ResetUE: %d\n"), (kl_val(iter)->m_Params.ResetUE)); + tfprintf (pDev->hLog,_T("ResetTimeDelay: %d\n"), kl_val(iter)->m_Params.ResetTimeDelay); + fflush(pDev->hLog); + TCHAR szOutPutFileName[MAX_PATH] = {0}; + TCHAR szComFileName[MAX_PATH] = {0}; + strncpy( szOutPutFileName, pUploadSpec->strOutputFileName.s, MAX_PATH ); + tfprintf (pDev->hLog,_T("Output File: %s\n"), szOutPutFileName); + //begin to save upload data into FILE + FILE* ofs = NULL; + if (pUploadSpec->bCreateNewFile) + { + ofs = fopen(szOutPutFileName,"a+"); + } + else + { + ofs = fopen(szOutPutFileName,"a+"); + } + if ( ofs == NULL ) + { + tfprintf (pDev->hLog,_T("Can't open file: %s\n"), szOutPutFileName); + return FALSE; + } + + strncpy( szComFileName, pUploadSpec->strComparisonFileName.s, MAX_PATH); + tfprintf (pDev->hLog,_T("Comparison File: %s\n"), szComFileName); + TCHAR Msg[1024]; + sprintf(Msg,_T("Begin to upload data from 0x%x to 0x%x to file %s"),kl_val(iter)->m_Params.Offset*512,kl_val(iter)->m_Params.Offset*512+kl_val(iter)->m_Params.DataSize,szOutPutFileName); + tfprintf (pDev->hLog,_T("%s"),Msg); + //Report(kProcDebugLog, Msg, pDev); + + if ( UploadDataHeader(pDev->pWtpComm, &pUploadSpec->m_Params ) ) + { + unsigned int UploadBytes = pUploadSpec->m_Params.DataSize; + if(me->m_nFlashDataPageSize>0&&pUploadSpec->m_Params.IncludeSpareAreas==UPLOAD_WITH_SPAREAREA) + { + UploadBytes +=(((int)(UploadBytes)/me->m_nFlashDataPageSize))*(me->m_nFlashDataPageSize/32); + } + unsigned int BytesRemaining = UploadBytes; + tfprintf (pDev->hLog,_T("\n All Bytes to upload is %d\n"),BytesRemaining); + unsigned int BytesWritten = 0; + unsigned int uiWholesize = BytesRemaining; + unsigned int BytesReceived = 0; + unsigned int uiBufferLength = 0; + if(pUploadSpec->m_Params.IncludeSpareAreas==UPLOAD_WITH_SPAREAREA) + { + sprintf(Msg,_T("\nUploading data with Spare Area from 0x%x to 0x%x to file %s\n"),kl_val(iter)->m_Params.Offset*512,kl_val(iter)->m_Params.Offset*512+OriginalUploadBytes,szOutPutFileName); + } + else + { + sprintf(Msg,_T("\nUploading data from 0x%x to 0x%x to file %s\n"),kl_val(iter)->m_Params.Offset*512,kl_val(iter)->m_Params.Offset*512+OriginalUploadBytes,szOutPutFileName); + } + + //Report(kProcDebugLog, Msg, pDev); + tprintf (_T("%s"),Msg); + BYTE* pUploadDataBuffer = (BYTE*) malloc(sizeof(BYTE)*8186); + WTPSTATUS* pWtpStatus = (WTPSTATUS*)malloc(sizeof(WTPSTATUS)); + while ( BytesRemaining > 0 ) + { + uiBufferLength = ( BytesRemainingpWtpComm, pUploadDataBuffer, uiBufferLength,pWtpStatus)) + { + + tprintf (_T("Error: Upload Failed!\n")); + free(pUploadDataBuffer); + + UINT32 ReturnCode = 0; + int i ; + for ( i = 0; i < 4; i++) + { + ReturnCode |= pWtpStatus->Data[i] << (8 * i); + } + if((pWtpStatus->DLEN >0)) + { + tfprintf (pDev->hLog,_T("\nAbort in upload data because of MESSAGE ERRORCODE \n")); + //ReportError(eProcState = kProcDebugLog, stBurningFlashError,_T("Upload data Error"), pDev,ReturnCode); + TCHAR szMessage[1024]; + tprintf (_T(" ERROR CODE: %X\n"), ReturnCode ); + //tfprintf (pDev->hLog,szMessage); + return FALSE; + + } + return FALSE; + } + else + { + fwrite(pUploadDataBuffer,sizeof(BYTE),uiBufferLength,ofs); + BytesWritten +=uiBufferLength; + double percentage; + BytesReceived += uiBufferLength; + percentage=(double)(BytesReceived)/(double)uiWholesize; + int nPercent = percentage*100; + tprintf (_T("Uploading file percentage is:%d\r"), nPercent); + BytesRemaining -= uiBufferLength; + + } + } + } + + free(pWtpStatus); + pWtpStatus = NULL; + tprintf(_T("Finish to upload data to file %s\n"),szOutPutFileName); + + //Report(kProcDebugLog, Msg, pDev); + free(pUploadDataBuffer); + + tfprintf (pDev->hLog,_T("Finish saving upload data file %s!\n"),szOutPutFileName); + fflush(pDev->hLog); + + } + else + { + tfprintf (pDev->hLog,_T("UploadDataheader Failed!\n")); + tprintf (_T("UploadDataheader Failed!\n")); + return FALSE; + } + + fclose(ofs); + + iter = kl_next(iter); + if(!Done(pDev->pWtpComm)) + { + tprintf(_T("Done CMD failed in Upload\n")); + break; + } + + + } + else + { + tfprintf (pDev->hLog,_T("GetParameters failed.....\n")); + tprintf(_T("GetParameters failed.....\n")); + return FALSE; + + } + } + + } + else + { + tfprintf (pDev->hLog,_T("GetProtocolVersion failed.....\n")); + tprintf(_T("GetProtocolVersion failed.....\n")); + return FALSE; + } + } + } + tfprintf (pDev->hLog ,_T("Upload procedure finished\n")); + fflush(pDev->hLog); + tprintf (_T("Upload procedure finished\n")); + WTPSTATUS WTPStatus = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; + Disconnect(pDev->pWtpComm,&WTPStatus); + + return TRUE; +} + + + +UINT32 WtptpDownLoad_GetWTPTPMSGReturnCode(struct CWtptpDownLoad *me,WTPSTATUS *pWtpStatus) +{ + UINT32 ReturnCode = 0; + int i ; + for ( i = 0; i < 4; i++) + { + ReturnCode |= pWtpStatus->Data[i+2] << (8 * i); + } + return ReturnCode; +} +BOOL WtptpDownLoad_ValidateWTPTPMSGReport(struct CWtptpDownLoad *me,PDEVICE pDev, WTPSTATUS *pWtpStatus, UINT32 *ReturnCode) +{ + *ReturnCode = 0; + int i ; + for ( i = 0; i < 4; i++) + { + *ReturnCode |= pWtpStatus->Data[i+2] << (8 * i); + } + + if(pWtpStatus->Data[0]== WTPTPNOTIFICATION) + { + BOOL bFound = FALSE; + for (i = 0; i < MAXNOTIFICATIONSCODES; i++) + { + if (WTPTPNotificationMsg[i].NotificationCode == *ReturnCode) + { +#ifndef COMPRESSDATA + tfprintf (pDev->hLog,_T("\nWTPTP Notification: %s ,Notification code is :0x%X\n"),WTPTPNotificationMsg[i].Description,*ReturnCode); +#else + tfprintf (pDev->hLog,_T("\nWTPTP Notification code is :0x%X\n"),*ReturnCode); +#endif + fflush(pDev->hLog); + bFound = TRUE; + break;; + } + + } + if(!bFound) + { + TCHAR Msg[1024]; + sprintf(Msg,_T("\nNotification Code: 0x%X\n"),*ReturnCode); + tfprintf (pDev->hLog,_T("%s"),Msg); + fflush(pDev->hLog); + } + + if((*ReturnCode == PlatformEraseAllFlash)&&(!me->m_bEraseAllFlash)) + { + + tfprintf (pDev->hLog,_T("\n Do unexpected erase all flash in OBM\n")); + fflush(pDev->hLog); + return FALSE; + + } + + if((*ReturnCode == PlatformResetBBT)&&(!me->m_bResetBBT)) + { + + tfprintf (pDev->hLog,_T("\n Do unexpected ResetBBT in OBM\n")); + fflush(pDev->hLog); + return FALSE; + + } + return TRUE; + } + else if(pWtpStatus->Data[0]== WTPTPERRORREPORT) + { + TCHAR szMessage[1024]; + BOOL bFound = FALSE; + for (i = 0; i < MAXNOTIFICATIONSCODES; i++) + { + if (WTPTPErrorCodes[i].ErrorCode == *ReturnCode) + { + #ifndef COMPRESSDATA + sprintf (szMessage,_T("\nWTPTP Error: %s 0x%X\n"),WTPTPErrorCodes[i].Description,*ReturnCode ); + #else + sprintf (szMessage,_T("\nWTPTP Error: 0x%X\n"),*ReturnCode ); + #endif + tfprintf (pDev->hLog,_T("%s"),szMessage); + fflush(pDev->hLog); + bFound = TRUE; + break; + } + } + tfprintf (pDev->hLog,_T("%s"),szMessage); + return FALSE; + + } + return TRUE; +} + +BOOL WtptpDownLoad_WTPTPDownLoad(struct CWtptpDownLoad *me,PDEVICE pDev) +{ +#if PRINTLOG + tprintf(_T("Enter into WTPTPDownLoad\n")); +#endif + if(pDev->ThreadExit==STOPFLAG) + { + tfprintf(pDev->hLog,_T("Thread is to be exit")); + fflush(pDev->hLog); + return FALSE; + } + + pDev->kProState = kProcDebugLog; + _tcscpy(pDev->szCurrentMsg,_T("Enter into WTPTPDownLoad....")); + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + tfprintf (pDev->hLog,_T("%s"),pDev->szCurrentMsg); + + MESSAGE_MODES currentMessageMode = DISABLED; + WTPSTATUS WtpStatus = {0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; + isFastDownload (pDev->pWtpComm,SET, TRUE); + tfprintf (pDev->hLog,_T("Enter WTPTPDownload\n")); + fflush(pDev->hLog); + if(me->m_bEraseAllFlash) + { + tfprintf (pDev->hLog,_T("Erase all flag FBF file\n")); + } + if(me->m_bResetBBT) + { + tfprintf (pDev->hLog,_T("Reset flag in FBF file\n")); + } + if(me->m_bGetBadBlk) + { + tfprintf (pDev->hLog,_T("Flash bad block report is enabled in FBF file\n")); + } + if(me->m_bImageCrcEnable) + { + tfprintf (pDev->hLog,_T("Image Crc report is enabled in FBF file\n")); + } + t_ImageFileList *pimgfilesList; + if(pDev->nDevType == kBootLoader) + { + pimgfilesList = me->m_plBootLoaderImageList; + } + else if(pDev->nDevType == kBootRom) + { + pimgfilesList = me->m_plBootRomImageList; + } + else + { + return FALSE; + } + + FILE* hFile; + eProcessState eProcState; + TCHAR szFileName[MAX_PATH]; + UINT64 uiAllimgsize=0; + UINT64 uidownloadsize=0; + UINT32 uiCurrentFileSize = 0; + for (t_ImageFileListConstIter ite = kl_begin(*pimgfilesList); ite != kl_end(*pimgfilesList); ite = kl_next(ite)) + { + if(TIMH == kl_val(ite).nFileType) + { + //uiAllimgsize += GetFileSize(ite->strImageFile.c_str()); + uiAllimgsize += BinFileWtp_GetFileSize(&gBinFileWtp,kl_val(ite).strImageFile); + } + else + { + //uiAllimgsize += GetFileSize(ite->strImageFile.c_str()) - IMAGEID_LEN; + uiAllimgsize += BinFileWtp_GetFileSize(&gBinFileWtp,kl_val(ite).strImageFile) - IMAGEID_LEN; + } + } + + SetPacketSize(pDev->pWtpComm,USBPACKETSIZE); + + //FileIndex = nImages; // Just in case user supplies more files than required + BOOL retry=TRUE; + int retryAttempts = 3; + tfprintf (pDev->hLog,_T("\nBegin OpenUsbPort\n")); + SetPortType(pDev->pWtpComm,0);//set usb port as default + + + pDev->kProState = kProcDebugLog; + _tcscpy(pDev->szCurrentMsg,_T("Start Image Downloading...")); + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + tfprintf (pDev->hLog,_T("%s"),pDev->szCurrentMsg); + + if(me->m_bCustPreamble) + { + tfprintf (pDev->hLog,_T("\nCustomize Preamble Mode\n")); + } + else + { + tfprintf (pDev->hLog,_T("\nOriginal Preamble Mode\n")); + } + fflush(pDev->hLog); + + int nImageNum = kl_size(stifl,*pimgfilesList); + for (int i = 0; i < nImageNum; ++i) + { + if(pDev->ThreadExit == STOPFLAG) + { + return FALSE; + } + + if(0 != GetLinuxDev(pDev->pWtpComm)->hDevHandle) + { + char strDownloadImgName[256]; + if (WtptpDownLoad_DownloadImage (me,pDev,i, pimgfilesList,uiAllimgsize,&uidownloadsize,nImageNum,strDownloadImgName) == FALSE) + { + + tfprintf (pDev->hLog,_T("\nRetry to DownloadImage: %s\n"),strDownloadImgName); + return FALSE; + } + else //Download completed + { + + if(i!=0&&pDev->nDevType == kBootLoader) + { + + WTPSTATUS *pWtpStatus = (WTPSTATUS*)malloc(sizeof(WTPSTATUS)); + hFile = NULL;//_tfopen(strDownloadImgName.c_str(),_T("rb")); + double npercent; + BOOL bIsEraseAllDone = FALSE; + BOOL bIsEraseAllOnlyDone = FALSE; + //fseek (hFile,0L,SEEK_END); + BinFileWtp_FseekBin(&gBinFileWtp,strDownloadImgName,0L,SEEK_END); + if(i==0) + { + uiCurrentFileSize = BinFileWtp_GetFileSize(&gBinFileWtp,strDownloadImgName); + //uiCurrentFileSize = ftell(hFile); + } + else + { + uiCurrentFileSize = BinFileWtp_GetFileSize(&gBinFileWtp,strDownloadImgName) - 4; + //uiCurrentFileSize = ftell(hFile)-4; + } + long uiDownloadSize = 0; + UINT32 WtptpReturnCode = 0; + UINT32 uiBurntSize = 4096;// first sector is no need to burnt to falsh , so add this size + //fclose(hFile); + + tfprintf (pDev->hLog,_T("\nBegin Buring image %s,size %d\n"),strDownloadImgName,uiCurrentFileSize); + + pWtpStatus->Status = ACK; + + switch(me->m_ePlatformType) + { + case PLAT_PXA92x: + { + tfprintf (pDev->hLog,_T("\n PXA92x burning flash.... \n")); + fflush(pDev->hLog); + while (pWtpStatus->Status == ACK) + { + + + if(pDev->ThreadExit == STOPFLAG) + { + pDev->kProState = kProcAborting; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + if (! GetWtpMessage (pDev->pWtpComm,pWtpStatus)) + { + break; + } + else + { + + if(pWtpStatus->Data[0]>ERRORFLAG) + { + tfprintf (pDev->hLog,_T("\nAbort becasue of MESSAGE ERRORCODE \n")); + TCHAR szMessage[1024]; + sprintf (szMessage,_T(" ERROR CODE: %X\n"), pWtpStatus->Data[0] ); + tfprintf (pDev->hLog,_T("%s"),szMessage); + fflush(pDev->hLog); + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + } + // This is to add a delay for WTPTP while the flash is being erased by DKB. + if (pWtpStatus->Data[0] == PXA92x_PlatformBusy ) + { + pDev->kProState = kProcDebugLog; + _tcscpy(pDev->szCurrentMsg,_T("Begin Burning flash...")); + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + tfprintf (pDev->hLog,_T("%s"),pDev->szCurrentMsg); + fflush(pDev->hLog); + pDev->kProState=kProcBurningFlash; + unsigned long int DelayTime_tmp = 0; + do + { + + GetWtpMessage( pDev->pWtpComm,pWtpStatus); + if(pWtpStatus->Data[0]>ERRORFLAG) + { + tfprintf (pDev->hLog,_T("\nAbort becasue of MESSAGE ERRORCODE \n")); + TCHAR szMessage[1024]; + sprintf (szMessage,_T(" ERROR CODE: %X\n"), pWtpStatus->Data[0] ); + tfprintf (pDev->hLog,_T("%s"),szMessage); + fflush(pDev->hLog); + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + if ( pWtpStatus->Data[0] == PXA92x_PlatformDisconnect ) + break; + if(pDev->ThreadExit == STOPFLAG) + { + pDev->kProState = kProcAborting; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + + if(DelayTime_tmp>2000*5000) + { + tfprintf (pDev->hLog,_T("\nBurning flash timeout\n")); + fflush(pDev->hLog); + break; + } + usleep(1000000); + npercent= (double)uiDownloadSize*100/(double)uiCurrentFileSize; + uiDownloadSize +=me->m_nBurningSpeed*1000; + + pDev->kProState = kProcBurningFlash; + pDev->npercent = (int)npercent; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + DelayTime_tmp += 1000; + } + while(pWtpStatus->Data[0] != PXA92x_PlatformReady); + } + if ( pWtpStatus->Data[0] == PXA92x_PlatformDisconnect ) + { + tfprintf (pDev->hLog,_T("\nAbort in Burnning flash\n")); + fflush(pDev->hLog); + pDev->kProState = kProcDebugLog; + _tcscpy(pDev->szCurrentMsg,_T("Abort in Burnning flash")); + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + + if ( pWtpStatus->Data[0] == PXA92x_PlatformReady ) + { + npercent = 100; + pDev->kProState = kProcBurningFlash; + pDev->npercent = (int)npercent; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + tfprintf (pDev->hLog,_T("\nBurnning flash Successfully\n")); + fflush(pDev->hLog); + + break; + } + + } + } + break; + default: + { + + while (pWtpStatus->Status == ACK) + { + + if(pDev->ThreadExit == STOPFLAG) + { + pDev->kProState = kProcAborting; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + + + if (! GetWtpMessage (pDev->pWtpComm,pWtpStatus)) + { + tfprintf (pDev->hLog,_T("\nGetWtpMessage failed before burning flash\n")); + fflush(pDev->hLog); + break; + if((pWtpStatus->DLEN >0)) + { + if(! WtptpDownLoad_ValidateWTPTPMSGReport(me,pDev,pWtpStatus,&WtptpReturnCode)) + { + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + } + } + // This is to add a delay for WTPTP while the flash is being erased by DKB. + if (WtptpDownLoad_GetWTPTPMSGReturnCode(me,pWtpStatus)== PlatformBusy ) + { + + pDev->kProState = kProcDebugLog; + _tcscpy(pDev->szCurrentMsg,_T("Begin Burning flash...")); + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + tfprintf (pDev->hLog,_T("%s"),pDev->szCurrentMsg); + fflush(pDev->hLog); + + + + pDev->kProState=kProcBurningFlash; + unsigned long int DelayTime_tmp = 0; + UINT32 FlashSize = 0; + do + { + + if(pDev->ThreadExit == STOPFLAG) + { + pDev->kProState = kProcAborting; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + + if(!GetWtpMessage(pDev->pWtpComm,pWtpStatus)) + { + tfprintf (pDev->hLog,_T("\nGetWtpMessage failed\n")); + fflush(pDev->hLog); + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + else + { + + if((pWtpStatus->DLEN >0)) + { + if(!WtptpDownLoad_ValidateWTPTPMSGReport(me,pDev,pWtpStatus,&WtptpReturnCode)) + { + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + + else + { + if(pWtpStatus->Data[0]== WTPTPNOTIFICATION_BURNTSIZE) + { + uiBurntSize+=WtptpReturnCode; + // make a round to burnt size to multiple of 4096(FBF_Sector size) + if(uiBurntSize%4096) + { + uiBurntSize+=((4096-(uiBurntSize%4096))); + } + WtptpReturnCode = 0; + npercent= (double)uiBurntSize/(double)uiCurrentFileSize; + npercent = npercent*100; + uiDownloadSize =uiBurntSize; + + pDev->npercent = (int)npercent; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + } + if((WtptpReturnCode == PlatformEraseAllFlashDone)) + { + bIsEraseAllDone = TRUE; + + } + + if((WtptpReturnCode == PlatformEraseAllFlashWithoutBurnDone)) + { + bIsEraseAllOnlyDone = TRUE; + + } + + + + } + + } + + } + + if(DelayTime_tmp>2000*5000) + { + tfprintf (pDev->hLog,_T("\nBurning flash timeout\n")); + fflush(pDev->hLog); + break; + } + usleep(1000000); + DelayTime_tmp += 1000; + + if(me->m_bEraseAllFlash&&(!bIsEraseAllDone)&&(i==1)) + { + + if(FLASH_SPINOR==me->m_FlashType) + { + if(FlashSize == 0x2000000)//32M + npercent+=SPINOR_32M_ERASE_SPEED; + else + npercent+=SPINOR_16M_ERASE_SPEED; + } + else if(FLASH_EMMC == me->m_FlashType) + { + npercent+=EMMC_ERASE_SPPED; + } + else if(FLASH_SPINAND==me->m_FlashType) + { + npercent+=EMMC_ERASE_SPPED; + } + else + npercent+=NAND_ERASE_SPPED; + pDev->kProState = kProcEraseAllFlash; + pDev->npercent = (int)npercent; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + + } + + if(me->m_bEraseAllFlashOnly&&(!bIsEraseAllOnlyDone)&&(i==1)) + { + + + if(FLASH_SPINOR==me->m_FlashType) + { + if(FlashSize == 0x2000000)//32M + npercent+=SPINOR_32M_ERASE_SPEED; + else + npercent+=SPINOR_16M_ERASE_SPEED; + } + else if(FLASH_EMMC == me->m_FlashType) + { + npercent+=EMMC_ERASE_SPPED; + } + else if(FLASH_SPINAND==me->m_FlashType) + { + npercent+=EMMC_ERASE_SPPED; + } + else + npercent+=NAND_ERASE_SPPED; + pDev->kProState = kProcEraseAllFlash; + pDev->npercent = (int)npercent; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + + } + + + else + { + npercent= (double)uiDownloadSize*100/(double)uiCurrentFileSize; + uiDownloadSize +=me->m_nBurningSpeed*1000; + + pDev->kProState = kProcBurningFlash; + pDev->npercent = (int)npercent; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + } + WtptpDownLoad_Report(me); + + if ( WtptpDownLoad_GetWTPTPMSGReturnCode(me,pWtpStatus) == PlatformDisconnect ) + break; + + } + while(WtptpDownLoad_GetWTPTPMSGReturnCode(me,pWtpStatus) != PlatformReady); + } + if ( WtptpDownLoad_GetWTPTPMSGReturnCode(me,pWtpStatus) == PlatformDisconnect ) + { + tfprintf (pDev->hLog,_T("\nPlatformDisconnect\n")); + fflush(pDev->hLog); + pDev->kProState = kProcDebugLog; + _tcscpy(pDev->szCurrentMsg,_T("PlatformDisconnect")); + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + tfprintf (pDev->hLog,_T("%s"),pDev->szCurrentMsg); + fflush(pDev->hLog); + free(pWtpStatus); + pWtpStatus = NULL; + return FALSE; + } + + if ( WtptpDownLoad_GetWTPTPMSGReturnCode(me,pWtpStatus) == PlatformReady ) + { + + npercent = 100; + pDev->kProState = kProcBurningFlash; + pDev->npercent = (int)npercent; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + + + tfprintf (pDev->hLog,_T("\nBurnning flash Successfully\n")); + fflush(pDev->hLog); + break; + } + + } + } + break; + } + + free(pWtpStatus); + pWtpStatus = NULL; + } + } + + } + else + { + tfprintf (pDev->hLog,_T("\nIOThead is not exist\n")); + fclose (pDev->hLog); + return FALSE; + } + } + + WTPSTATUS WTPStatus = {0x00, 0x00, 0x00, 0x01, 0x00, 0x00}; + + if(me->m_bImageCrcEnable && (!me->m_bEraseAllFlashOnly)) + { + tfprintf (pDev->hLog,_T("\nGetting ImageCrc...\n")); + fflush(pDev->hLog); + + if (!GetImageCrc(pDev->pWtpComm,&WTPStatus)) + { + _tcscpy(pDev->szCurrentMsg,_T("CRCERROR")); + pDev->kProState = kProcBurningFlash; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + + tfprintf (pDev->hLog,_T("Error: GetImageCrc failed!\n")); + fflush(pDev->hLog); + //return FALSE;//Don't interrupt here, can do it in the mainfrm.cpp + } + else + { + pImageCRCInfo pImageCrc = (pImageCRCInfo)WTPStatus.Data; + memset(&pDev->DevImageCrc, 0, sizeof(ImageCRCInfo)); + memcpy(&pDev->DevImageCrc, pImageCrc, sizeof(ImageCRCInfo)); + _tcscpy(pDev->szCurrentMsg,_T("CRCS")); + pDev->kProState = kProcBurningFlash; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + + fprintf(pDev->hLog, _T("\n MCPID: 0x%x, ImageNum: %d, "),le32toh(pImageCrc->MCPID), le32toh(pImageCrc->ImageNum)); + for(UINT32 i = 0; i < le32toh(pImageCrc->ImageNum); i++) + fprintf(pDev->hLog, _T("\n ImageID: 0x%x, CrcData: 0x%08X"),le32toh(pImageCrc->ImageCRC[i].ImageID), le32toh(pImageCrc->ImageCRC[i].CRC32)); + + } + } + + tfprintf (pDev->hLog,_T("\nBegin to disconnect\n")); + Disconnect(pDev->pWtpComm,&WTPStatus); + + if(kBootRom== pDev->nDevType && PLAT_EDEN_A0 == me->m_ePlatformType) + { + usleep(100000); //100ms + } + + tfprintf (pDev->hLog,_T("\nFinish to disconnect\n")); + fflush(pDev->hLog); + + _tcscpy(pDev->szCurrentMsg,_T("Finish to disconnect")); + pDev->kProState = kProcDebugLog; + WtptpDownLoad_AddDisplayInfoDevice(me,pDev); + WtptpDownLoad_Report(me); + + return TRUE; +} + + + + +BOOL WtptpDownLoad_TerminateBL(struct CWtptpDownLoad *me) +{ + if(!me->m_binitFlag) // there is no InitializeBL + return TRUE; +#if PRINTLOG + tprintf(_T("\nTerminateBL.....\n")); +#endif + pthread_mutex_lock(&me->Quit_mutex); + me->m_bTerminateDownload = TRUE; + me->m_bTerminateUSBDetect = TRUE; + pthread_mutex_unlock(&me->Quit_mutex); + + // kill all download thread for all device + usleep(2000000); + pthread_mutex_lock(&me->DeviceList_mutex); + for(t_DeviceIter iter = kl_begin(me->m_WtptpDeviceList);iter != kl_end(me->m_WtptpDeviceList); iter = kl_next(iter)) + { + if((kl_val(iter)) != NULL) + { + (kl_val(iter))->ThreadExit = STOPFLAG; + SetExitHandle((kl_val(iter))->pWtpComm,1); + usleep(2000000); + CloseUsbPort((kl_val(iter))->pWtpComm); + free((kl_val(iter))->pWtpComm); + (kl_val(iter))->pWtpComm = NULL; + free(kl_val(iter)); + } + } + pthread_mutex_unlock(&me->DeviceList_mutex); +#if PRINTLOG + tprintf(_T("\nplease wait .....\n")); +#endif + usleep(100000); + BinFileWtp_CloseBinFIle(&gBinFileWtp); + return TRUE; +} + +#if 0 +BOOL WtptpDownLoadInitializeBLEx(struct CWtptpDownLoad *me,PInstanceParams pInstParam,const TCHAR * pszBLFfileName ,const TCHAR * pszFBFTimFile,const TCHAR * pszFBFfileName) +{ +#ifdef PCIEDOWNLOAD + _tprintf(_T("\nInitializeBLEx parameter.....\n")); + + if(_tcslen(pszBLFfileName)==0) + { + _tprintf(_T("\nblf file is empty.....\n")); + return FALSE; + } + else + { + if(_taccess(pszBLFfileName,0)!=0) + { + _tprintf(_T("\n%s is not exist.....\n"),pszBLFfileName); + return FALSE; + } + + } + + + if(_tcslen(pszFBFTimFile)==0) + { + _tprintf(_T("\nFBF tim file is empty.....\n")); + return FALSE; + } + else + { + if(_taccess(pszFBFTimFile,0)!=0) + { + _tprintf(_T("\n%s is not exist.....\n"),pszFBFTimFile); + return FALSE; + } + + } + + if(_tcslen(pszFBFfileName)==0) + { + _tprintf(_T("\nFBF file is empty.....\n")); + return FALSE; + } + else + { + if(_taccess(pszFBFfileName,0)!=0) + { + _tprintf(_T("\n%s is not exist.....\n"),pszFBFfileName); + return FALSE; + } + + } + me->m_bOnlyOBMDownload = TRUE; + + CParser blfparser; + me->m_ePlatformType = blfparser.GetPlatFormType(pszBLFfileName); + me->m_FlashType = blfparser.GetFlashType(pszBLFfileName); + pInstParam->PlaformType = me->m_ePlatformType; + pInstParam->FlashType = me->m_FlashType; + // m_nFlashDataPageSize = pInstParam->FlashPageSize; + + /*tstring ss = pszFBFTimFile; + m_ImageList.push_back(ss); + ss = pszFBFfileName; + m_ImageList.push_back(ss);*/ + DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC* lpDdrFlashDLImgInfoSpec = new DDR_FLASH_DOWNLOADIMAGE_INFO_SPEC(); + lpDdrFlashDLImgInfoSpec->pImagelist->push_back(new string(pszFBFTimFile)); + lpDdrFlashDLImgInfoSpec->pImagelist->push_back(new string(pszFBFfileName)); + pInstParam->pDownloadImagesList = new t_DdrFlashDownloadImgInfoList(); + pInstParam->pDownloadImagesList->push_back(lpDdrFlashDLImgInfoSpec); + + pInstParam->pszDKBbin = NULL; + pInstParam->pszDKBTim = NULL; + pInstParam->pszWTMFile = NULL; + pInstParam->pszOBMFile = NULL; + + pInstParam->PlaformType = (unsigned int)m_ePlatformType; + pInstParam->FlashType = (unsigned int)m_FlashType; + + eEraseAllMode m_eEraseAllFlash = (eEraseAllMode)blfparser.GetBlfInt(pszFLASH_OPTIONS,pszERASE_ALL_FLASH,0,pszBLFfileName); + BOOL m_bResetBBT = blfparser.GetBlfInt(pszFLASH_OPTIONS,pszRESET_BBT,-1,pszBLFfileName); + + unsigned int nCommand = 0; + if(m_eEraseAllFlash==ERASE_ALL_BEFOREBURNING) + { + nCommand|=DLCMD_DO_ERASE_ALL_FLASH_MSK; + } + if(m_bResetBBT) + { + nCommand|=DLCMD_DO_RESETBBT_MSK; + } + if(m_eEraseAllFlash==ERASE_ALL_WIHTOUTBURNING) + { + nCommand|=DLCMD_DO_ERASE_ALL_FLASH_ONLY_MSK; + } + + pInstParam->Commands =nCommand; + + + WtptpDownLoad_InitializeBL(me,pInstParam); +#endif + return TRUE; +} +#endif + + +BOOL WtptpDownLoad_InitializeBL(struct CWtptpDownLoad *me,PInstanceParams pInstParam) +{ + int iBootRomFileIndex = 0,iBootLoaderFileIndex=0; + me->m_nBootRomDevNum = 0; + me->m_nBootLoaderDevNum = 0; + readlink ("/proc/self/exe", me->m_szSWDPath, MAX_FILE_LENGTH); + TCHAR *p = _tcsrchr( me->m_szSWDPath,'/'); + if(p) *p = 0; +#if PRINTLOG + tprintf(_T("SWD Path is %s \n"),me->m_szSWDPath); + //getwd(m_szSWDPath); + tprintf(_T("Begin to initialize WTPTPDownload parameter\n")); +#endif + if (strlen(g_LogPath) > 0) + { + strncpy(me->m_szSWDPath,g_LogPath,_countof(me->m_szSWDPath)); + } + int res = pthread_mutex_init(&me->DeviceList_mutex,NULL); + if(res!=0) + { +#if PRINTLOG + perror(_T("DeviceList_mutex initialization failed")); +#endif + exit(EXIT_FAILURE); + } + /*res = pthread_mutex_init(&Device_mutex,NULL); + if(res!=0) + { + perror(_T("Device Mutex initialization failed")); + exit(EXIT_FAILURE); + }*/ + + res = pthread_mutex_init(&me->Quit_mutex,NULL); + if(res!=0) + { +#if PRINTLOG + perror(_T("Quit_mutex initialization failed")); +#endif + exit(EXIT_FAILURE); + } + + res = pthread_mutex_init(&me->callback_mutex,NULL); + if(res!=0) + { +#if PRINTLOG + perror(_T("callback_mutex initialization failed")); +#endif + exit(EXIT_FAILURE); + } + + + kl_clear(pdisl,me->m_DisplayInfoList); + me->m_lpInstParam = pInstParam; + me->m_nFlashDataPageSize = pInstParam->FlashPageSize; + me->m_ePlatformType = (ePlatForm)pInstParam->PlaformType; + me->m_FlashType = (eFlashType)pInstParam->FlashType; + + if(me->m_FlashType==FLASH_NAND) + { + me->m_nBurningSpeed = NAND_BURNNING_SPEED; + } + else if(me->m_FlashType==FLASH_EMMC) + { + me->m_nBurningSpeed = EMMC_BURNNING_SPEED; + } + else + { + me->m_nBurningSpeed = SPINOR_BURNNING_SPEED; + } + + me->m_bEraseAllFlash = (((pInstParam->Commands)&DLCMD_DO_ERASE_ALL_FLASH_MSK) ==DLCMD_DO_ERASE_ALL_FLASH_MSK)?TRUE:FALSE; + me->m_bEraseAllFlashOnly = (((pInstParam->Commands)&DLCMD_DO_ERASE_ALL_FLASH_ONLY_MSK) ==DLCMD_DO_ERASE_ALL_FLASH_ONLY_MSK)?TRUE:FALSE; + me->m_bResetBBT = (((pInstParam->Commands)&DLCMD_DO_RESETBBT_MSK) == DLCMD_DO_RESETBBT_MSK)?TRUE:FALSE; + me->m_bSingleDownload = (pInstParam->DownloadMode==1)?TRUE:FALSE; + me->m_bGetBadBlk = (pInstParam->GetBadBlk==1)?TRUE:FALSE; + me->m_bImageCrcEnable = (pInstParam->ImageCrcEn==1)?TRUE:FALSE; + memset(me->m_szPrimaryDkbPath,0,sizeof(me->m_szPrimaryDkbPath)); + memset(me->m_szPrimTimPath,0,sizeof(me->m_szPrimTimPath)); + memset(me->m_szOBMPath, 0, sizeof(me->m_szOBMPath)); + memset(me->m_szWTMPath, 0, sizeof(me->m_szWTMPath)); + memset(me->m_szTZIPath, 0 ,sizeof(me->m_szTZIPath)); + + me->m_lpUpLoadDataSpecList = me->m_lpInstParam->pUploadSpecs; + me->m_bDumpFlash = (((pInstParam->Commands)&DLCMD_DO_UPLOAD_DATA_MSK) ==DLCMD_DO_UPLOAD_DATA_MSK)?TRUE:FALSE; + me->m_uFlashBadBlockRate = pInstParam->ReservedVal[0];//坏块率门限 + + + if(me->m_bDumpFlash) + { + if (!WtptpDownLoad_prepareDumpFlashParam(me,pInstParam)) + { + printf (_T("prepareDumpFlashParam failed.\n")); + return FALSE; + } + } + else if(me->m_bEnabledJtag) + { + if (!WtptpDownLoad_prepareEnabledJtagImg(me,pInstParam)) + { + printf(_T("Prepare enabledJtag images failed.\n")); + return FALSE; + } + } + else + { + BinFileWtp_InitParameter(&gBinFileWtp); + if (!WtptpDownLoad_prepareDownloadImg(me,pInstParam)) + { +#if PRINTLOG + printf(_T("Prepared download image failed.")); +#endif + return FALSE; + } +#if PRINTLOG + printf(_T("\nParse DKB Tim image.\n")); +#endif + BinFileWtp_InitRead(&gBinFileWtp); + if (!WtptpDownLoad_ParseTim(me,&me->m_lBootRomImageWithDDRList)) + { + printf(_T("Parse DKB Tim failed.\n")); + return FALSE; + } +#if PRINTLOG + printf(_T("\nParse FBF Tim image.\n")); +#endif + if (!WtptpDownLoad_ParseTim(me,&me->m_lBootLoaderImageWithDDRList)) + { + printf(_T("Parse FBF Tim failed.\n")); + return FALSE; + } + } + + + me->m_binitFlag = TRUE; +#if PRINTLOG + tprintf(_T("\nComplete to Initilize parameter\n")); +#endif + fflush(stdout); + + res = pthread_create(&me->DetectThread, NULL,WtptpDownLoad_WtptpDeviceDetectThread ,me); + if(res!=0) + { +#if PRINTLOG + perror (_T("\nThread creation failed\n")); +#endif + return FALSE; + } + else + { +#if PRINTLOG + tprintf(_T("\nBegin to detect wtptp device....\n")); +#endif + } + fflush(stdout); + return TRUE; +} + + +BOOL WtptpDownLoad_prepareDumpFlashParam(struct CWtptpDownLoad *me,const PInstanceParams pInstParam) +{ +#if PRINTLOG + printf(_T("Prepare UpLoadDataSpecList for dump flash\n")); +#endif + if(NULL == pInstParam->pUploadSpecs || kl_size(pudsl,*pInstParam->pUploadSpecs)==0) + { + printf(_T(" Upload area list is NULL")); + return FALSE; + } + + + me->m_lpUpLoadDataSpecList = (t_UpLoadDataSpecList*)malloc(sizeof(t_UpLoadDataSpecList)); + (*me->m_lpUpLoadDataSpecList) = kl_init(pudsl); + for (t_UpLoadDataSpecIter iter = kl_begin(*pInstParam->pUploadSpecs); + iter != kl_end(*pInstParam->pUploadSpecs); + iter = kl_next(iter)) + { + pUPLOAD_DATA_SPEC pTmp; + pTmp = (UPLOAD_DATA_SPEC*)malloc(sizeof(UPLOAD_DATA_SPEC)); + *kl_pushp(pudsl,*me->m_lpUpLoadDataSpecList) = pTmp; + NewUPLOAD_DATA_SPEC(pTmp,kl_val(iter)); + } + + return TRUE; +} + +BOOL WtptpDownLoad_prepareEnabledJtagImg(struct CWtptpDownLoad *me,const PInstanceParams pInstParam) +{ +#if PRINTLOG + printf(_T("Prepare BR images for enabled Jtag\n")); +#endif + int nJtagEnabledImgIdx = 0; + if (pInstParam->pszDKBTim) //check if user enter any security file path. + { + if (!IsFileExist(pInstParam->pszDKBTim)) + { + tprintf(_T("DKBTim file %s is not exist"),pInstParam->pszDKBTim); + return FALSE; + } + struct stImageFile stTmp; + stTmp.nFileType = TIMH; + stTmp.strImageFile = pInstParam->pszDKBTim; + *kl_pushp(stifl,*me->m_plJtagEnabledImageList) = stTmp; + } + else + { + tprintf(_T("Miss Timheader image in re-enabled jtag.")); + return FALSE; + } + + if (pInstParam->pszDKBbin) + { + if (!IsFileExist(pInstParam->pszDKBbin)) + { + tprintf(_T("DKB file %s is not exist"),pInstParam->pszDKBbin); + return FALSE; + } + struct stImageFile stTmp; + stTmp.nFileType = OBMI; + stTmp.strImageFile = pInstParam->pszDKBbin; + *kl_pushp(stifl,*me->m_plJtagEnabledImageList) = stTmp; + } + else + { + tprintf(_T("Miss OBM image in re-enabled jtag.")); + return FALSE; + } + + if (pInstParam->pszTZIIFile) + { + if (!IsFileExist(pInstParam->pszTZIIFile)) + { + tprintf(_T("TZII file %s is not exist"),pInstParam->pszTZIIFile); + return FALSE; + } + struct stImageFile stTmp; + stTmp.nFileType = TZII; + stTmp.strImageFile = pInstParam->pszTZIIFile; + *kl_pushp(stifl,*me->m_plJtagEnabledImageList) = stTmp; + } + + for (t_ImageFileListIter ite = kl_begin(*me->m_plJtagEnabledImageList); ite != kl_end(*me->m_plJtagEnabledImageList); ite = kl_next(ite)) + { + if (!IsFileExist(kl_val(ite).strImageFile)) + { + tprintf(_T("%s image don't exist:%s"),stringer(kl_val(ite).nFileType),kl_val(ite).strImageFile); + return FALSE; + } + } + + + +/* if (pInstParam->pszJTAGKeyFile) // check if user enter any security file path. + { + if (!IsFileExist(pInstParam->pszJTAGKeyFile)) + { + tprintf(_T("JTAGKeyFile file %s is not exist "),pInstParam->pszJTAGKeyFile); + return FALSE; + } + m_strJtagKeyFile = pInstParam->pszJTAGKeyFile; + } + else + { + tprintf(_T("Miss JtagKeyFile in re-enabled jtag.")); + return FALSE; + }*/ + return TRUE; +} + +BOOL WtptpDownLoad_prepareDownloadImg(struct CWtptpDownLoad *me,const PInstanceParams pInstParam) +{ + BOOL bIsBootRomlistPrepared = FALSE; + if(0==kl_size(dfdil,*pInstParam->pDownloadImagesList)) + return FALSE; + + + t_DdrFlashDownloadImgInfoIter DDRDownloadIMGIter = kl_begin(*pInstParam->pDownloadImagesList); + while(DDRDownloadIMGIter!= kl_end(*pInstParam->pDownloadImagesList)) + { + + struct stImageFileByDDR *pImageFileByDDRBL = (struct stImageFileByDDR*)malloc(sizeof(struct stImageFileByDDR)); + memset(pImageFileByDDRBL,0,sizeof(struct stImageFileByDDR)); + New_stImageFileByDDR(pImageFileByDDRBL); + t_stringListIter imageiter = kl_begin(*kl_val(DDRDownloadIMGIter)->pImagelist); + me->m_uTotalDDRTypeNum = kl_val(DDRDownloadIMGIter)->TotalVendorDDRTypeNum; + me->m_uTotalFlashTypeNum =kl_val(DDRDownloadIMGIter)->TotalFlashTypeNum; + + while(imageiter!=kl_end(*kl_val(DDRDownloadIMGIter)->pImagelist)) + { + //if (!IsFileExist((*imageiter)->c_str())) + if (!BinFileWtp_IsFileExist(&gBinFileWtp,kl_val(imageiter)->s)) + { + tprintf(_T("File %s can't exist\n"),kl_val(imageiter)->s); + return FALSE; + } + struct stImageFile stiTmp; + stiTmp.nFileType = 0; + stiTmp.strImageFile = kl_val(imageiter)->s; + *kl_pushp(stifl,pImageFileByDDRBL->ImageFileList) = stiTmp; + imageiter = kl_next(imageiter); + } + + pImageFileByDDRBL->sDDRVendorID = (kl_val(DDRDownloadIMGIter))->sVendorDDRId; + pImageFileByDDRBL->sFlashInfo = (kl_val(DDRDownloadIMGIter))->sFlashInfo; + *kl_pushp(stifdl,me->m_lBootLoaderImageWithDDRList) = pImageFileByDDRBL; + + if(bIsBootRomlistPrepared) + { + DDRDownloadIMGIter = kl_next(DDRDownloadIMGIter); + continue; + } + + bIsBootRomlistPrepared = TRUE; + struct stImageFileByDDR *pImageFileByDDRBR = (struct stImageFileByDDR*)malloc(sizeof(struct stImageFileByDDR)); + memset(pImageFileByDDRBR,0,sizeof(struct stImageFileByDDR)); + New_stImageFileByDDR(pImageFileByDDRBR); + pImageFileByDDRBR->sDDRVendorID = kl_val(DDRDownloadIMGIter)->sVendorDDRId; + pImageFileByDDRBR->sFlashInfo = kl_val(DDRDownloadIMGIter)->sFlashInfo; + + + if (pInstParam->pszDKBTim) // check if user enter any security file path. + { + //if (!IsFileExist(pInstParam->pszDKBTim)) + if (!BinFileWtp_IsFileExist(&gBinFileWtp,pInstParam->pszDKBTim)) + { + tprintf(_T("DKB Tim header file %s is not exist "),pInstParam->pszDKBTim); + return FALSE; + } + struct stImageFile stiTmp; + stiTmp.nFileType = TIMH; + stiTmp.strImageFile = pInstParam->pszDKBTim; + *kl_pushp(stifl,pImageFileByDDRBR->ImageFileList) = stiTmp; + } + + if(pInstParam->pszDKBbin) + { + //if (!IsFileExist(pInstParam->pszDKBbin)) + if (!BinFileWtp_IsFileExist(&gBinFileWtp,pInstParam->pszDKBbin)) + { + tprintf(_T("DKB Bin file %s is not exist "),pInstParam->pszDKBbin); + return FALSE; + } + struct stImageFile stiTmp; + stiTmp.nFileType = DKBI; + stiTmp.strImageFile = pInstParam->pszDKBbin; + *kl_pushp(stifl,pImageFileByDDRBR->ImageFileList) = stiTmp; + } + + if (PLAT_MMP2 == me->m_ePlatformType) + { + if(pInstParam->pszOBMFile) + { + //if (!IsFileExist(pInstParam->pszOBMFile)) + if (!BinFileWtp_IsFileExist(&gBinFileWtp,pInstParam->pszOBMFile)) + { + tprintf(_T("OBM Bin file %s is not exist "),pInstParam->pszOBMFile); + return FALSE; + } + struct stImageFile stiTmp; + stiTmp.nFileType = OBMI; + stiTmp.strImageFile = pInstParam->pszOBMFile; + *kl_pushp(stifl,pImageFileByDDRBR->ImageFileList) = stiTmp; + } + } + + if (PLAT_MMP2 == me->m_ePlatformType + || PLAT_MMP3 == me->m_ePlatformType + || PLAT_EDEN== me->m_ePlatformType + || PLAT_EDEN_A0 == me->m_ePlatformType + || PLAT_HELAN2== me->m_ePlatformType + || PLAT_HELAN3== me->m_ePlatformType + || PLAT_HELAN4== me->m_ePlatformType) + { + if(pInstParam->pszWTMFile) + { + //if (!IsFileExist(pInstParam->pszWTMFile)) + if (!BinFileWtp_IsFileExist(&gBinFileWtp,pInstParam->pszWTMFile)) + { + tprintf(_T("WTM Bin file %s is not exist "),pInstParam->pszWTMFile); + } + struct stImageFile stiTmp; + stiTmp.nFileType = WTMI; + stiTmp.strImageFile = pInstParam->pszWTMFile; + *kl_pushp(stifl,pImageFileByDDRBR->ImageFileList) = stiTmp; + } + } + + if (PLAT_EDEN== me->m_ePlatformType + || PLAT_EDEN_A0 == me->m_ePlatformType + || PLAT_HELAN2== me->m_ePlatformType + || PLAT_ULC1 == me->m_ePlatformType + || PLAT_HELAN3== me->m_ePlatformType + || PLAT_HELAN4== me->m_ePlatformType + || PLAT_ULC2== me->m_ePlatformType) + { + if(pInstParam->pszTZIIFile) + { + //if (!IsFileExist(pInstParam->pszTZIIFile)) + if (!BinFileWtp_IsFileExist(&gBinFileWtp,pInstParam->pszTZIIFile)) + { + tprintf(_T("TZI Bin file %s is not exist "),pInstParam->pszTZIIFile); + return FALSE; + } + struct stImageFile stiTmp; + stiTmp.nFileType = TZII; + stiTmp.strImageFile = pInstParam->pszTZIIFile; + *kl_pushp(stifl,pImageFileByDDRBR->ImageFileList) = stiTmp; + } + } + + *kl_pushp(stifdl,me->m_lBootRomImageWithDDRList) = pImageFileByDDRBR; + + DDRDownloadIMGIter = kl_next(DDRDownloadIMGIter); + } + + + t_ImageFileByDDRIter Iter = kl_begin(me->m_lBootRomImageWithDDRList); + me->m_plBootRomImageList = &((kl_val(Iter))->ImageFileList); +#if PRINTLOG + printf("Prepared download image\n"); +#endif + return TRUE; +} + +void WtptpDownLoad_ResetParameter(struct CWtptpDownLoad *me) +{ + me->m_plBootRomImageList=NULL; + me->m_plBootLoaderImageList=NULL; + me->m_plJtagEnabledImageList=NULL; + + t_ImageFileByDDRIter DDRDownloadIMGIter = kl_begin(me->m_lBootRomImageWithDDRList); + while(DDRDownloadIMGIter!= kl_end(me->m_lBootRomImageWithDDRList)) + { + free(kl_val(DDRDownloadIMGIter)); + DDRDownloadIMGIter = kl_next(DDRDownloadIMGIter); + } + kl_clear(stifdl,me->m_lBootRomImageWithDDRList); + + DDRDownloadIMGIter = kl_begin(me->m_lBootLoaderImageWithDDRList); + while(DDRDownloadIMGIter!= kl_end(me->m_lBootLoaderImageWithDDRList)) + { + free(kl_val(DDRDownloadIMGIter)); + DDRDownloadIMGIter = kl_next(DDRDownloadIMGIter); + } + kl_clear(stifdl,me->m_lBootLoaderImageWithDDRList); + + DDRDownloadIMGIter = kl_begin(me->m_lJtagEnabledImageWithDDRList); + while(DDRDownloadIMGIter!= kl_end(me->m_lJtagEnabledImageWithDDRList)) + { + free(kl_val(DDRDownloadIMGIter)); + DDRDownloadIMGIter = kl_next(DDRDownloadIMGIter); + } + kl_clear(stifdl,me->m_lJtagEnabledImageWithDDRList); + +} + +eDDREMMCMatchResult WtptpDownLoad_HandleDownloadImagesByDDRIDandEMMCSize(struct CWtptpDownLoad *me,UINT32 uiDdrVendorId, UINT32 uiDdrUnitSize,UINT32 uiEMMCSize) +{ + if(kl_size(stifdl,me->m_lBootLoaderImageWithDDRList)>1) + { + //Verify�Ƿ���map������ֱ�ӱ��� + //verify�Dz�������׼����DDR�б�����ڣ���ֱ�ӱ������ڣ�����m_lBootRomImageList/m_lBootLoaderImageList/m_lJtagEnabledImageList + BOOL IsVendorIDisknown = FALSE; + for (int idx = 0; idx < MAX_DDR_VENDOR_NUM; ++idx) + { + if (vendorDdrPidNameMap[idx].nDdrVendorID == uiDdrVendorId) + { + IsVendorIDisknown = TRUE; + break; + } + } + + if(!IsVendorIDisknown) + return kDDRMismatchError; + + + BOOL bIsDDRFileispreparedBL = FALSE; + BOOL bIsEMMCFileispreparedBL = FALSE; + UINT32 uiDdrPid = (uiDdrVendorId<<8)|uiDdrUnitSize; + t_ImageFileByDDRIter Iter = kl_begin(me->m_lBootLoaderImageWithDDRList); + while(Iter!=kl_end(me->m_lBootLoaderImageWithDDRList)) + { + + if(me->m_uTotalDDRTypeNum>0&&1==me->m_uTotalFlashTypeNum)//Multiple DDR and Single EMMC size type + { + if(Str2Uint32((kl_val(Iter))->sDDRVendorID.s) == uiDdrPid) + { + bIsDDRFileispreparedBL = TRUE; + bIsEMMCFileispreparedBL = TRUE; + me->m_plBootLoaderImageList = &(kl_val(Iter))->ImageFileList; + break; + } + } + else if(me->m_uTotalDDRTypeNum==0&&me->m_uTotalFlashTypeNum>1)//Single DDR and Multiple EMMC size type + { + UINT32 uiEMMCSizecfg = TranslateEx((kl_val(Iter))->sFlashInfo)/UNIT_GB; + //��(*Iter)->sEMMCSizeת��Ϊ����֮���512M��������֮�Ƚ� + if( uiEMMCSizecfg== uiEMMCSize) + { + bIsDDRFileispreparedBL = TRUE; + bIsEMMCFileispreparedBL = TRUE; + me->m_plBootLoaderImageList = &(kl_val(Iter))->ImageFileList; + break; + } + + } + else if(me->m_uTotalFlashTypeNum>1&&me->m_uTotalDDRTypeNum>0)//Multiple DDR and Multiple EMMC size type + { + UINT32 uiEMMCSizecfg = TranslateEx((kl_val(Iter))->sFlashInfo)/UNIT_GB; + if(uiEMMCSizecfg == uiEMMCSize&& Str2Uint32((kl_val(Iter))->sDDRVendorID.s) == uiDdrPid) + { + bIsDDRFileispreparedBL = TRUE; + bIsEMMCFileispreparedBL = TRUE; + me->m_plBootLoaderImageList = &(kl_val(Iter))->ImageFileList; + break; + } + } + else + { + return kImagePreparationError; //total DDR num and EMMCSize num maybe error + } + Iter = kl_next(Iter); + } + if(me->m_uTotalDDRTypeNum>0&&!bIsDDRFileispreparedBL) + return kDDRMismatchError; + if(me->m_uTotalFlashTypeNum>1&&!bIsDDRFileispreparedBL) + return kDDRMismatchError; + + } + else + { + t_ImageFileByDDRIter Iter = kl_begin(me->m_lBootLoaderImageWithDDRList); + me->m_plBootLoaderImageList = &((kl_val(Iter))->ImageFileList); + } + + return kMatchNoError; +} + +eDDREMMCMatchResult WtptpDownLoad_HandleNandDLImgByDDRID(struct CWtptpDownLoad *me,UINT32 uiDdrVendorId, UINT32 uiDdrUnitSize) +{ + if(kl_size(stifdl,me->m_lBootLoaderImageWithDDRList)>1) + { + BOOL bFound = FALSE; + for (int idx = 0; idx < MAX_DDR_VENDOR_NUM; ++idx) + { + if (vendorDdrPidNameMap[idx].nDdrVendorID == uiDdrVendorId) + { + bFound = TRUE; + break; + } + } + + if(!bFound) + { + return kDDRMismatchError; + } + + UINT32 uiDdrPid = (uiDdrVendorId<<8)|uiDdrUnitSize; + BOOL bFoundNandId = FALSE; + for(t_ImageFileByDDRIter ite = kl_begin(me->m_lBootLoaderImageWithDDRList); ite != kl_end(me->m_lBootLoaderImageWithDDRList); ite = kl_next(ite)) + { + if(Str2Uint32((kl_val(ite))->sDDRVendorID.s) == uiDdrPid) + { + me->m_plBootLoaderImageList = &(kl_val(ite))->ImageFileList; + bFoundNandId = TRUE; + break; + } + } + + if(!bFoundNandId) + { + return kDDRMismatchError; + } + } + else + { + t_ImageFileByDDRIter Iter = kl_begin(me->m_lBootLoaderImageWithDDRList); + me->m_plBootLoaderImageList = &((kl_val(Iter))->ImageFileList); + } + + return kMatchNoError; +} + + +char* WtptpDownLoad_replace_all(char* str,const char* old_value,const char* new_value) +{ + char buf[256]={0}; + char *p = NULL,*pstr = str; + int lo = strlen(old_value); + p = strstr(pstr, old_value); + while (p) + { + strncat(buf, pstr, p-pstr); + strcat(buf, new_value); + pstr = p + lo; + p = strstr(pstr,old_value); + } + strcat(buf,pstr); + strcpy(str, buf); + return str; +} + + +EDeviceType WtptpDownLoad_GetDeviceType(struct CWtptpDownLoad *me,ePlatForm ePlatfromType,const char* strDate,const char* strVersion ,const char* strProcessor) +{ + for (int idx = 0; idx < sizeof(gstFlatformBLInfoSet)/sizeof(gstFlatformBLInfoSet[0]); ++idx) + { + if (gstFlatformBLInfoSet[idx].ePlatFormType == ePlatfromType) + { + if((NULL != strstr(strDate, gstFlatformBLInfoSet[idx].strBLDate)) + &&(NULL != strstr(strProcessor,gstFlatformBLInfoSet[idx].strBLProcessor) ) + &&(NULL != strstr(strVersion,gstFlatformBLInfoSet[idx].strBLVersion)) ) + { + return kBootLoader; + } + else + { + return kBootRom; + } + } + } + return kNone; +} + + + diff --git a/fbfdownloader/src/WtptpDownloader.h b/fbfdownloader/src/WtptpDownloader.h new file mode 100644 index 00000000..dcd50020 --- /dev/null +++ b/fbfdownloader/src/WtptpDownloader.h @@ -0,0 +1,229 @@ +#pragma once +#include +#include "ParaDefine.h" +#include "define.h" +#include "WTPdef.h" +#include "ConvetEdian.h" +#include "ApplicationINI.h" +#include "Typedef.h" +#include "BulkDevNonDrv_Linux.h" +#include "BinFileWtp.h" + +/******************************************************************************************************************* + + (C) Copyright 20011 Marvell Semiconductor Hefei Ltd. All Rights Reserved + + *******************************************************************************************************************/ + + +#define MMP2_BOOTLOADER_PROCESSOR _T("MMP2") +#define MMP2_BOOTLOADER_VERSION _T("3215") +#define MMP2_BOOTLOADER_DATE _T("12052009") + +#define WKNG_BOOTLOADER_PROCESSOR _T("WKNG") +#define WKNG_BOOTLOADER_VERSION _T("3301") +#define WKNG_BOOTLOADER_DATE _T("06172011") + +#define NEVO_BOOTLOADER_PROCESSOR _T("NEVO") +#define NEVO_BOOTLOADER_VERSION _T("3301") +#define NEVO_BOOTLOADER_DATE _T("08182011") + +#define MMP3_BOOTLOADER_PROCESSOR _T("MMP3") +#define MMP3_BOOTLOADER_VERSION _T("3302") +#define MMP3_BOOTLOADER_DATE _T("03082012") + + +#define PXA92X_BOOTLOADER_PROCESSOR _T("TVTD") +#define PXA92X_BOOTLOADER_VERSION _T("3211") +#define PXA92X_BOOTLOADER_DATE _T("06242009") + +#define EMEI_BOOTLOADER_PROCESSOR _T("EMEI") +#define EMEI_BOOTLOADER_VERSION _T("3304") +#define EMEI_BOOTLOADER_DATE _T("07022012") + +#define HELAN_BOOTLOADER_PROCESSOR _T("HELN") +#define HELAN_BOOTLOADER_VERSION _T("3307") +#define HELAN_BOOTLOADER_DATE _T("01152013") + +#define EDEN_BOOTLOADER_PROCESSOR _T("EDEN") +#define EDEN_BOOTLOADER_VERSION _T("3307") +#define EDEN_BOOTLOADER_DATE _T("04162013") + +#define NEZHA3_BOOTLOADER_PROCESSOR _T("NZA3") +#define NEZHA3_BOOTLOADER_VERSION _T("3311") +#define NEZHA3_BOOTLOADER_DATE _T("06012014") + + +#define HELAN2_BOOTLOADER_PROCESSOR _T("HLN2") +#define HELAN2_BOOTLOADER_VERSION _T("3308") +#define HELAN2_BOOTLOADER_DATE _T("02122014") + +#define EDENA0_BOOTLOADER_PROCESSOR _T("EDEN") +#define EDENA0_BOOTLOADER_VERSION _T("3307") +#define EDENA0_BOOTLOADER_DATE _T("02142014") + +#define ULC1_BOOTLOADER_PROCESSOR _T("ULC1") +#define ULC1_BOOTLOADER_VERSION _T("3313") +#define ULC1_BOOTLOADER_DATE _T("09172014") + +#define HELAN3_BOOTLOADER_PROCESSOR _T("HLN3") +#define HELAN3_BOOTLOADER_VERSION _T("3313") +#define HELAN3_BOOTLOADER_DATE _T("11052014") + +#define HELAN4_BOOTLOADER_PROCESSOR _T("HLN4") +#define HELAN4_BOOTLOADER_VERSION _T("3313") +#define HELAN4_BOOTLOADER_DATE _T("25032015") + +#define ULC2_BOOTLOADER_PROCESSOR _T("ULC2") +#define ULC2_BOOTLOADER_VERSION _T("3313") +#define ULC2_BOOTLOADER_DATE _T("08052015") + +struct stFlatformBootLoaderInfo{ + ePlatForm ePlatFormType; + const char* strBLDate; + const char* strBLProcessor; + const char* strBLVersion; +}; + +extern const struct stFlatformBootLoaderInfo gstFlatformBLInfoSet[]; + +#define USBPACKETSIZE 0x4000 +//#define USBPACKETSIZE 4096 //Modify for FD don't work on NEVO c0 and VMWare download +static const int NAND_BURNNING_SPEED = 1000; //per ms +static const int EMMC_BURNNING_SPEED = 8000 ;//per ms +static const int SPINOR_BURNNING_SPEED = 90 ;//per ms + + +static const double SPINOR_16M_ERASE_SPEED = 1.3; +static const double SPINOR_32M_ERASE_SPEED = 0.52; +static const double SPINAND_128M_ERASE_SPEED = 2.8; +static const double EMMC_ERASE_SPPED = 96.0; +static const double NAND_ERASE_SPPED = 49.0; +#define DLCMD_DO_ERASE_ALL_FLASH_MSK 1 +#define DLCMD_DO_UPLOAD_DATA_MSK 2 +#define DLCMD_DO_RESETBBT_MSK 4 +#define DLCMD_DO_ERASE_ALL_FLASH_ONLY_MSK 16 +#define MAX_IMG_FILES 100 +#define MAX_DOWNLOAD_DEVICENUM 32 + +#define IMAGEID_LEN 4 +#define stringer(x) #x +void NewCWtptpDownLoad (struct CWtptpDownLoad *me); +BOOL WtptpDownLoad_DownloadImage(struct CWtptpDownLoad *me,PDEVICE pDev, int iFile,const t_ImageFileList* plImgFileList, UINT64 uiAllimgsize,UINT64 *uidownloadsize,int nImages,char* strDownloadImgName); +BYTE WtptpDownLoad_AckWithImageName (struct CWtptpDownLoad *me,const UINT32 ImageType,TCHAR *szFileName,const t_ImageFileList* plImageList); +BOOL WtptpDownLoad_ParseTim (struct CWtptpDownLoad *me,t_ImageFileByDDRList* ImageFileByDDRlist); +BOOL WtptpDownLoad_SetAndWaitForThreadExit(struct CWtptpDownLoad *me,PDEVICE pDev); +BOOL WtptpDownLoad_RemoveEntryList(struct CWtptpDownLoad *me,PDEVICE pDev); +BOOL WtptpDownLoad_GetDeviceBootType(struct CWtptpDownLoad *me,PDEVICE pDev); +BOOL WtptpDownLoad_UploadDataFromTarget(struct CWtptpDownLoad *me,PDEVICE pDev); +BOOL WtptpDownLoad_OpenDevice(struct CWtptpDownLoad *me,PDEVICE pDev); +void WtptpDownLoad_WtptpOpenDevice(struct CWtptpDownLoad *me,struct CWtptpDownLoad *pWtptpDownLoad, USB_HANDLE *pLinuxUsb); +BOOL WtptpDownLoad_ValidateWTPTPMSGReport(struct CWtptpDownLoad *me,PDEVICE pDev, WTPSTATUS *pWtpStatus, UINT32 *ReturnCode); +UINT32 WtptpDownLoad_GetWTPTPMSGReturnCode(struct CWtptpDownLoad *me,WTPSTATUS *pWtpStatus); +BOOL WtptpDownLoad_WTPTPDownLoad (struct CWtptpDownLoad *me,PDEVICE pDev); +void WtptpDownLoad_Report(struct CWtptpDownLoad *me); +void WtptpDownLoad_AddDisplayInfoDevice(struct CWtptpDownLoad *me,PDEVICE pDev); +void WtptpDownLoad_RemoveDisplayInfoDevice(struct CWtptpDownLoad *me,PDEVICE pDev); +void WtptpDownLoad_ResetParameter(struct CWtptpDownLoad *me); +BOOL WtptpDownLoad_prepareDumpFlashParam(struct CWtptpDownLoad *me,const PInstanceParams pInstParam); +BOOL WtptpDownLoad_prepareEnabledJtagImg(struct CWtptpDownLoad *me,const PInstanceParams pInstParam); +BOOL WtptpDownLoad_prepareDownloadImg(struct CWtptpDownLoad *me,const PInstanceParams pInstParam); +static PVOID WtptpDownLoad_BootRomIOThread(PVOID Arg); +static PVOID WtptpDownLoad_BootLoaderIOThread(PVOID Arg); +static PVOID WtptpDownLoad_BootLoaderUploadThread(PVOID Arg); +static PVOID WtptpDownLoad_WtptpDeviceDetectThread(PVOID Arg); +static int WtptpDownLoad_init_hotplug_sock(); +BOOL WtptpDownLoad_InitializeBL(struct CWtptpDownLoad *me,PInstanceParams pInstParam); +//BOOL WtptpDownLoadInitializeBLEx(struct CWtptpDownLoad *me,PInstanceParams pInstParam,const TCHAR * pszBLFfileName ,const TCHAR * pszFBFTimFile,const TCHAR * pszFBFfileName); +BOOL WtptpDownLoad_TerminateBL(struct CWtptpDownLoad *me); +void WtptpDownLoad_SetBootDeviceType(struct CWtptpDownLoad *me,PDEVICE pDev,EDeviceType eDevieBootType); +eDDREMMCMatchResult WtptpDownLoad_HandleDownloadImagesByDDRIDandEMMCSize(struct CWtptpDownLoad *me,UINT32 uiDdrVendorId, UINT32 uiDdrUnitSize,UINT32 uiEMMCSize); +eDDREMMCMatchResult WtptpDownLoad_HandleNandDLImgByDDRID(struct CWtptpDownLoad *me,UINT32 uiDdrVendorId, UINT32 uiDdrUnitSize); +char* WtptpDownLoad_replace_all(char* str,const char* old_value,const char* new_value) ; +EDeviceType WtptpDownLoad_GetDeviceType(struct CWtptpDownLoad *me,ePlatForm ePlatfromType,const char* strDate,const char* strVersion ,const char* strProcessor); +void DelCWtptpDownLoad (struct CWtptpDownLoad *me); + + + +struct CWtptpDownLoad +{ + struct CConvertLT2B MyConvertLT2B; + TCHAR m_szPrimaryDkbPath[MAX_PATH]; + TCHAR m_szPrimTimPath[MAX_PATH]; + TCHAR m_szSecondaryFlasherPath[MAX_PATH]; + TCHAR m_szOBMPath[MAX_PATH]; + TCHAR m_szWTMPath[MAX_PATH]; + TCHAR m_szSWDPath[MAX_PATH]; + TCHAR m_szTZIPath[MAX_PATH]; + UINT32 m_nFlashDataPageSize ; + UINT32 m_nBurningSpeed; + BOOL m_binitFlag; + volatile BOOL m_bTerminateDownload; + + int m_uTotalDDRTypeNum; + int m_uTotalFlashTypeNum; + int m_uFlashBadBlockRate;//坏块率门限 m_uFlashBadBlockRate/10000 + + t_ImageFileList* m_plBootRomImageList; + t_ImageFileList* m_plBootLoaderImageList; + t_ImageFileList* m_plJtagEnabledImageList; + + + t_ImageFileByDDRList m_lBootRomImageWithDDRList; + t_ImageFileByDDRList m_lBootLoaderImageWithDDRList; + t_ImageFileByDDRList m_lJtagEnabledImageWithDDRList; + + BOOL m_bDumpFlash; //to do upload in wtptpdownload + BOOL m_bEnabledJtag; + + BOOL m_bInitialiezed ; // Indicates whether the InitializeBL was called (and was TerminateBL called afterwards) + BOOL m_bTermination ; + BOOL m_bUploadFromTarget ; //to do upload in wtptpdownload +// + BOOL m_bCustPreamble ; + BOOL m_bTrusted; + BOOL m_bEraseAllFlash ; + BOOL m_bEraseAllFlashOnly; + BOOL m_bResetBBT ; + BOOL m_bDebugTrace; + BOOL m_bOnlyOBMDownload; + volatile BOOL m_bTerminateUSBDetect; + BOOL m_bSingleDownload; + BOOL m_bGetBadBlk; + BOOL m_bImageCrcEnable; + BOOL m_bIsLittleEndian; + ePlatForm m_ePlatformType; + eFlashType m_FlashType; + t_DeviceList m_WtptpDeviceList; + t_DisplayInfoList m_DisplayInfoList; + + + PInstanceParams m_lpInstParam ; + //pWTPTPREAMBLECOMMAND m_lpCustPreambleCmd ; + t_UpLoadDataSpecList* m_lpUpLoadDataSpecList ; + int m_nBootRomDevNum ; + int m_nBootLoaderDevNum ; + int m_nUploadDevNum; + pthread_t BootRomTypeThread[MAX_DOWNLOAD_DEVICENUM]; + pthread_t BootLoaderTypeThread[MAX_DOWNLOAD_DEVICENUM]; + pthread_t UploadThread[MAX_DOWNLOAD_DEVICENUM]; + pthread_t DetectThread; + + pthread_mutex_t DeviceList_mutex; + //pthread_mutex_t Device_mutex; + pthread_mutex_t Quit_mutex; + pthread_mutex_t callback_mutex; + + + + + + + + + +}; + + + + diff --git a/fbfdownloader/src/define.h b/fbfdownloader/src/define.h new file mode 100644 index 00000000..2ec543cc --- /dev/null +++ b/fbfdownloader/src/define.h @@ -0,0 +1,145 @@ + +#ifndef DEFINE_H +#define DEFINE_H +#include "./Typedef.h" +#include "ParaDefine.h" +#include +#include +#include "kstring.h" + +#define MAX_PATH 1024 +struct CWtpComm; +struct CWtptpDownLoad; +#define RXTIMEOUT 10000 +#define TXTIMEOUT 5000 +#define WTPTPERRORREPORT 1 +#define WTPTPNOTIFICATION 0 +#define WTPTPNOTIFICATION_BURNTSIZE 2 +#define WTPTPNOTIFICATION_UPLOAD 3 +#define WTPTPNOTIFICATION_FLASHSIZE 4 +#define WTPTPREPORT_EXTENDED_FUSE_INFO 5 +#define WTPTPREPORT_UEINFO 6 + +#define MAX_FILE_PATH 1024 +#define USBPACKETSIZE 0x4000 + +#define STOPFLAG 1 +//#define DLCMD_DO_ERASE_ALL_FLASH_MSK 0 +//#define DLCMD_DO_UPLOAD_DATA_MSK 1 +//#define DLCMD_DO_RESETBBT_MSK 2 +//#define DLCMD_DO_CUSTMOIZEPREAMBLE_MSK 3 +//#define DLCMD_DO_ERASE_ALL_FLASH_ONLY_MSK 4 +//#define DLCMD_DO_ENABLE_JTAG_MSK 5 +typedef struct _DEVICE +{ + TCHAR UsbDevName[MAX_FILE_PATH];// + TCHAR LogFileName[MAX_FILE_PATH];// record downloding process to get debug information + TCHAR szCurrentMsg[MAX_FILE_PATH]; + BadBlockData DevBadBlk; // flash bad block data + ImageCRCInfo DevImageCrc; // CRC value of Images read back from flash + FILE *hLog; + int SerialNo; // Serial number of the device. + int npercent; + int nBootRomId, + nBootLoaderId, + nDevType; + struct CWtpComm *pWtpComm ; + volatile int ThreadExit; + pthread_t ThreadId; + eProcessState kProState; + +}DEVICE, *PDEVICE; + +typedef struct _DISPLAYINFO +{ + TCHAR UsbDevName[MAX_FILE_PATH]; + TCHAR szCurrentMsg[MAX_FILE_PATH]; + BadBlockData szBadBlk; // flash bad block data + ImageCRCInfo szImageCrc; // CRC value of Images read back from flash + eProcessState kProState; + int npercent; +}DISPLAYINFO,*PDISPLAYINFO; + +typedef struct _DOWNLOADTARGET +{ + PDEVICE pDev; + struct CWtptpDownLoad *pWtptpDownload; + +}DOWNLOADTARGET,*PDOWNLOADTARGET; + +#define __pdev_free(x) +KLIST_INIT(pdevl, PDEVICE, __pdev_free) +KLIST_INIT(pdisl, PDISPLAYINFO, __pdev_free) + +typedef klist_t(pdevl)* t_DeviceList; +typedef kliter_t(pdevl)* t_DeviceIter; +typedef klist_t(pdisl)* t_DisplayInfoList; +typedef kliter_t(pdisl)* t_DisplayInfoIter; + + +typedef enum _EDeviceType +{ + kNone = 0, + kBootRom = 1, + kBootLoader = 2, +}EDeviceType; + +enum eBootROM_Operation_Mode +{ + NonTrustedBoot1 = 0, + NonTrustedBoot2 = 1, + TrustedBoot = 2, + TamperBoot = 3 // BootROM will not boot device, so, OBM can't detect such mode. +}; + +typedef struct +{ + UINT32 ChipID : 16; // 0x1920 + UINT32 RevisionID : 8; // 0xB0 + UINT32 Reserved : 8; +}ChipIDInfo; + + +// extended message data +typedef struct { + UINT32 OEMKeyHash[8]; + UINT32 DeviceUID[2]; + enum eBootROM_Operation_Mode BRMode; + UINT32 MMCSerialNumber; + ChipIDInfo ChipId; +} ExMessageData, *pExMessageData; + +// extended message report +typedef struct { + UINT8 ReportType; + UINT8 ReportLength; + UINT8 TotalMsgNumber;//OBM分多次送消息,如果消息长度大于0x40 + UINT8 MsgIndex; //Current Msg Index + ExMessageData ReportData; +} ExMessageReport, *pExMessageReport; + +typedef struct { + UINT32 OEMKeyHash[8]; + UINT32 DeviceUID[2]; + UINT32 BRMode; + ChipIDInfo ChipId; + UINT8 eMMCInfo[16]; //128bit + UINT32 Reserved1; + UINT32 Reserved2; + UINT32 EmmcSize; //MB + UINT32 DDRSize; //MB +} UEInfo; +// extended message report +typedef struct { + UINT8 ReportType; + UINT8 ReportLength; + UINT8 TotalMsgNumber; //OBM分多次送消息,如果消息长度大于0x40 + UINT8 MsgIndex; //Current Msg Index + UEInfo ReportData; +} Ex2MessageReport, *pEx2MessageReport; + +typedef struct { + UEInfo UEMessageInfo; + TCHAR lpUsbPortAddress[260]; +} MessageUEInfoReport; +#endif diff --git a/fbfdownloader/src/downloader.h b/fbfdownloader/src/downloader.h new file mode 100644 index 00000000..e961ee56 --- /dev/null +++ b/fbfdownloader/src/downloader.h @@ -0,0 +1,377 @@ +/****************************************************************************** +** +** COPYRIGHT (C) 2000, 2002 Intel Corporation. +** +** This software as well as the software described in it is furnished under +** license and may only be used or copied in accordance with the terms of the +** license. The information in this file is furnished for informational use +** only, is subject to change without notice, and should not be construed as +** a commitment by Intel Corporation. Intel Corporation assumes no +** responsibility or liability for any errors or inaccuracies that may appear +** in this document or any software that may be provided in association with +** this document. +** Except as permitted by such license, no part of this document may be +** reproduced, stored in a retrieval system, or transmitted in any form or by +** any means without the express written consent of Intel Corporation. +** +** FILENAME: downloader.h +** +** PURPOSE: +** +** LAST MODIFIED: +******************************************************************************/ + +#ifndef DOWNLOADER_H +#define DOWNLOADER_H + +#include "Macrodef.h" +#include "Typedef.h" +#if !defined (LINUX) +//#include +#else +//#include "global_types_linux.h" +#endif// LINUX + +#define MAX_SIZE_OF_FILENAME_STRING 1024 + + +/* Concentration of all per-build identifiers */ +//#define DEBUG_BUILD + +#define MAX_NUMBER_OF_IMAGES 200 +//#define BLOCK_DEVICE_SECTOR_SIZE (32*1024) // 32 KB + +#ifdef FBFMAKEWEB +#define MAX_NUMBER_OF_IMAGE_STRUCTS_IN_DEVICE_HEADER 150 +#else +#define MAX_NUMBER_OF_IMAGE_STRUCTS_IN_DEVICE_HEADER 30 +#endif + +#define MASTER_BLOCK_HEADER_SIZE_IN_BYTES (sizeof(MasterBlockHeader)) +#define DEVICE_HEADER_SIZE_IN_BYTES (sizeof(DeviceHeader_VPXA92x)) +#define MAX_NUMBER_OF_FLASH_SECTIONS 3 +#define MAX_NUM_OF_FLASH_PROTECTION_REGIONS 10 + +/* end of per-build identifiers */ + +//#define DEBUG_BUILD + + +//#define FLASH_BLOCK_SIZE_IN_BYTES (64*1024) + + +/*-----------------12/22/2004 5:10PM---------------- + * Flash Commands + * --------------------------------------------------*/ +#define FLASH_CMD_WRITE_WORD_1 0x40 +#define FLASH_CMD_WRITE_WORD_2 0x0 + +#define FLASH_CMD_BLOCK_ERASE_1 0x20 +#define FLASH_CMD_BLOCK_ERASE_2 0xD0 /* Confirm erase */ + +#define FLASH_CMD_LOCK_BLOCK_1 0x60 +#define FLASH_CMD_LOCK_BLOCK_2 0x01 + +#define FLASH_CMD_UNLOCK_BLOCK_1 0x60 +#define FLASH_CMD_UNLOCK_BLOCK_2 0xD0 + +#define FLASH_CMD_RESET_FOR_READ 0xFF + +#define FLASH_CMD_CLR_SR 0x50 +#define FLASH_CMD_READ_SR 0x70 + +#define FLASH_ERASED_WORD_16BIT 0xffff +#define FLASH_ERASED_WORD_32BIT 0xffffffff + + +#define SR_STATUS_BLOCK_LOCKED 0x02 + +#define DLCMD_DO_VERIFY_WRITE 1 +#define DLCMD_DO_ERASE_BLOCKS 2 +#define DLCMD_WRITE_IMAGE 3 +#define DLCMD_DUMP_IMAGE 4 +#define DLCMD_IMAGE_TYPE_FIELD_BIT 4 /* bit 4 through 7*/ +#define DLCMD_IMAGE_TYPE_FIELD_SIZE_BITS 4 +#define DLCMD_IMAGE_SPARE_AREA_SZ_BIT 8 /* bit 8 through 15 */ +#define DLCMD_IMAGE_SPARE_AREA_SZ_FIELD_BITS 8 +#define DLCMD_IMAGE_DUMP_SPARE_BIT 16 +#define DLCMD_IMAGE_ABSOLUTE_FLASH_OFFSET_ENABLE_BIT 17 +#define DLCMD_IMAGE_USE_SECTOR_BASED_ADDRESSING 18 +#define DLCMD_PARTITION_NUM_FIELD_BIT (24) /* bit 24 through 31 */ +#define DLCMD_PARTITION_NUM_FIELD_BIT_SIZE (8) + + +//image type define +#define DLCMD_RAW_BINARY_IMAGE_TYPE (0) /* used when burning raw binary */ +#define DLCMD_WINDOWS_MOBILE_IMAGE_TYPE (1) /* used for WM image type */ +#define DLCMD_YAFFS_IMAGE_TYPE (2) /* this image type is used for YAFFS */ +#define DLCMD_UBIFS_IMAGE_TYPE (3) /* this image type is used for UBIFS */ +#define DLCMD_JFFS2_IMAGE_TYPE (4) /* this image type is used for JFFS2 */ +#define DLCMD_RND_IMAGE_TYPE (5) +#define DLCMD_SPARSE_IMAGE_TYPE (6) /* this image type is used for Sparse file of Android*/ +#define DLCMD_LZMA_IMAGE_TYPE (7) //OBM burn compressed image to flash +#define DLCMD_LZMA2_IMAGE_TYPE (8) //OBM burn decompressed image to flash +#define DLCMD_YAFFS_LZMA_IMAGE_TYPE (9) //SWD compress the image with lzma algorithm,write the compressed image to FBF for image type 9-12 +#define DLCMD_UBIFS_LZMA_IMAGE_TYPE (10) +#define DLCMD_JFFS2_LZMA_IMAGE_TYPE (11) +#define DLCMD_RAW_LZMA_IMAGE_TYPE (12) + + + +#define DLCMD_DUMP_BINARY_IMAGE_WITH_SPARE_TYPE (3) +#define DLCMD_ABSOLUTE_FLASH_OFFSET_TYPE (4) +#define DLCMD_ABSOLUTE_FLASH_OFFSET_WITH_SPARE_TYPE (5) + +/* general downloader commands */ +#define FBF_GENERAL_CMD_INITIALIZE_FLASH_MSK (1) +#define FBF_GENERAL_CMD_PRODUCTION_INIT_FLASH_MSK (2) +#define FBF_GENERAL_CMD_DISABLE_ERASE_WM_USER_PARTITIONS_MSK (4) +#define FBF_GENERAL_CMD_ERASE_ALL_FLASH_MSK (8) +#define FBF_GENERAL_CMD_PERFORM_TARGET_RESET_MSK (16) + +/* Flash parameters flags */ +#define FLASH_PARAMETERS_ENABLE_BIT 1 + +#define FLASH_ERASED_VALUE 0xFF + + +#define BUF_FLAG_PRIMARY_VALID 1 +#define BUF_FLAG_SECONDARY_VALID 2 +#define BUF_FLAG_IS_FIRST_SWITCH 4 + + +#define HARD_SECTOR_SIZE 512 //TBD - receive from ini + +//static int numOfFlashDevices = 0; /* number of flash devices */ + + + +typedef UINT16 CORE_ID; + +#define MANITOBA_CORE_ID 0xABAB +#define HERMON_CORE_ID 0xBBAC +#define BULVERDE_CORE_ID 0xABAD +#define TAVOR_CORE_ID 0x1f34 + + + +typedef UINT8 FLASH_FAMILY; + + +#define BOOT_BLOCKS_START_OFFSET 0x0 +#define NUM_OF_BOOT_BLOCKS 4 /* Boot blocks == TIM + OBM + PINMUX + OS Loader */ + + +/* Device Header flags */ +#define DEVICE_EXTERNAL_FLASH 1 + + +#define MAX_NUMBER_OF_FLASH_DEVICES_IN_MASTER_HEADER 4 +#define MAX_NUMBER_OF_FLASH_DEVICES 10 +#define MAX_RESEVERD_LEN 4 +#define MAX_NUM_SKIP_BLOCKS 32 + +#pragma pack (1) + + +typedef struct +{ + UINT32 tCH; /*Enable Signal Hold Time*/ + UINT32 tCS; /*Enable Signal Setup Time*/ + UINT32 tWH; /*ND_nWE high duration*/ + UINT32 tWP; /*ND_nWE pulse width*/ + UINT32 tRH; /*ND_nRE high duration*/ + UINT32 tRP; /*ND_nRE pulse width*/ + UINT32 tR; /*ND_nWE high to ND_nRE Low for Read*/ + UINT32 tWHR; /*ND_nWE High to ND_nRE Low for Read Status*/ + UINT32 tAR; /*ND_ALE Low to ND_nRE Low Delay*/ +} FlashTimingStruct; + +typedef struct +{ + UINT32 TotalNumOfBlocks; /*The total number of blocks in flash*/ + UINT32 FlashBlockSize; /*Block size in Flash*/ + UINT32 FlashOffset; /*Flash offset address*/ + UINT32 FlashBufferSize; /*Buffer size in Flash*/ + UINT32 NumberOfBlocksInBadBlockPool; /*What is the number of Blocks in the Bad Block Pool*/ + UINT32 SpareAreaSize; /* Flash Device spare area size */ + UINT32 ManufacturerBadBlockInfoOffset; /* Where manufacturer bad block information in flash*/ +} FlashSectionStruct; + +typedef struct +{ + FlashTimingStruct FlashTiming; /*Timing Parameters*/ + FlashSectionStruct FlashSection[MAX_NUMBER_OF_FLASH_SECTIONS]; +} FlashParametersStruct; + +typedef struct +{ + UINT32 flash_partition_size; /* flash partition size */ + UINT32 commands; /* bit switches */ + UINT32 First_Sector; /* First sector of the image in the block device */ + UINT32 length; /* Block length in bytes */ + UINT32 Flash_Start_Address; /* start address in flash */ + UINT32 Flash_block_size; /* flash device block size */ + UINT32 ChecksumFormatVersion2; /* new format version image checksum (left for backwards compatibility) */ +} ImageStruct_VPXA92x; + +typedef struct +{ + UINT32 Image_ID; /* image id*/ + UINT32 Image_In_TIM; /* indicate this image is in TIM or not*/ + UINT32 Flash_partition; /* partition number of the image */ + UINT32 Flash_erase_size; /* erase size of the image */ + UINT32 commands; /* bit switches */ + UINT32 First_Sector; /* First sector of the image in the block device */ + UINT32 length; /* Image length in bytes */ + UINT32 Flash_Start_Address; /* start address in flash */ + UINT32 Reserved[MAX_RESEVERD_LEN]; + UINT32 ChecksumFormatVersion2; /* new format version image checksum (left for backwards compatibility) */ +} ImageStruct_V11; + +typedef ImageStruct_V11 *PImageStruct_V11; +typedef struct +{ + UINT32 Total_Number_Of_SkipBlocks; // total numbers of skip blocks + UINT32 Skip_Blocks[MAX_NUM_SKIP_BLOCKS]; +} SkipBlocksInfoStruct; + + +typedef struct +{ + UINT32 EraseAll; // erase all flag for user partition + UINT32 ResetBBT; // indicate if reset BBT + UINT32 NandID; // nand flash ID + UINT32 Reserved[MAX_RESEVERD_LEN - 1]; + SkipBlocksInfoStruct Skip_Blocks_Struct; +}FlashOptStruct; + + +typedef struct +{ + UINT32 DeviceFlags; + FlashParametersStruct FlashParameters; /* Device Parameters */ + UINT8 nOfImages; /* number of images */ + UINT8 BufferSizeLSB; /* init to 0x00 */ + UINT16 AccessWidth; /* init to 0x0000 */ + CORE_ID Core_ID; + FLASH_FAMILY FlashFamily; /* Device Flags */ + UINT8 BufferSizeMSB; + ImageStruct_VPXA92x imageStruct[MAX_NUMBER_OF_IMAGE_STRUCTS_IN_DEVICE_HEADER]; /* array of image structs */ +} DeviceHeader_VPXA92x; + + +typedef struct +{ + UINT32 DeviceFlags; /* NAND, eMMC, SPI-NOR, etc*/ + UINT32 DeviceParameters[16]; /* Device Parameters, reserve 16 U32 here, will be defined depending on different devices */ + FlashOptStruct FlashOpt; + UINT32 ProductionMode; // production mode + UINT8 OptValue; // choice: 0 - Not reset after download, 1 - Reset after download + UINT8 ChipID; + UINT8 BBCS_EN; + UINT8 CRCS_EN; + UINT32 Reserved[MAX_RESEVERD_LEN-2]; + UINT32 nOfImages; /* number of images */ + ImageStruct_V11 imageStruct[MAX_NUMBER_OF_IMAGE_STRUCTS_IN_DEVICE_HEADER]; /* array of image structs */ +} DeviceHeader_V11; + +typedef DeviceHeader_VPXA92x *PDeviceHeader_VPXA92x; +typedef DeviceHeader_V11 *PDeviceHeader_V11; + + +#define NUM_OF_SUPPORTED_FLASH_DEVS 4 + +typedef struct +{ + char Unique[24]; + UINT16 Flash_Device_Spare_Area_Size[NUM_OF_SUPPORTED_FLASH_DEVS]; + UINT16 Format_Version; + UINT16 Size_of_Block; + UINT32 Bytes_To_Program; + UINT32 Bytes_To_Verify; + UINT32 Number_of_Bytes_To_Erase; + UINT32 Main_Commands; + UINT32 nOfDevices; /* number of devices to burn in parallel */ + UINT32 DLerVersion; /* Version of downloader current 1 */ + UINT32 deviceHeaderOffset[MAX_NUMBER_OF_FLASH_DEVICES_IN_MASTER_HEADER]; /* offset in Sector 0 for each flash device header */ +} MasterBlockHeader; +typedef MasterBlockHeader *PMasterBlockHeader; + + +typedef struct +{ + char Unique[24]; + UINT16 Flash_Device_Spare_Area_Size[NUM_OF_SUPPORTED_FLASH_DEVS]; + UINT16 Format_Version; + UINT16 Size_of_Block; + UINT32 Bytes_To_Program; + UINT32 Bytes_To_Verify; + UINT32 Number_of_Bytes_To_Erase; + UINT32 Main_Commands; + UINT32 nOfDevices; /* number of devices to burn in parallel */ + UINT32 DLerVersion; /* Version of downloader current 1 */ + UINT32 deviceHeaderOffset[MAX_NUMBER_OF_FLASH_DEVICES]; /* offset in Sector 0 for each flash device header */ +} MasterBlockHeader_PXA92x; +typedef MasterBlockHeader_PXA92x *PMasterBlockHeader_PXA92x; +#pragma pack () + +/*- Functions declaration */ + +void DLMakeMasterBlock(MasterBlockHeader* pMasterBlock, UINT32 nOfDevices, UINT32 DLerVersion); +void DLmakeDeviceHeader(DeviceHeader_V11* devHeader, UINT32 numOfImages); +UINT16 DLgetMasterBlockHeaderChksum(MasterBlockHeader *mBlockHeader); +void DLaddDeviceToMasterHeader(PMasterBlockHeader mbHeader); +void DLaddImageToDeviceHeader(PDeviceHeader_V11 pDev, PImageStruct_V11 pImageStruct); +//void startFlashProgramming(void); + +void DLmakeImageStruct( PImageStruct_V11 pImageStruct, + UINT32 commands, /* bit switches */ + UINT32 BlockDevice_Start_Block, /* start block in Block device */ + UINT32 length, /* Block length in bytes */ + UINT32 Flash_Start_Address /* start address in flash */ + ); + + +typedef struct +{ + UINT16* startAddr; + UINT32 nOfBlocksToErase; + UINT32 Flash_block_size; /* flash device block size */ +} BlockRange; + + +/* +typedef enum +{ + INVALID = 0, + READ_REQ, + READ_PENDING, + READ_COMPLETE, + FLASH_WRITING + +} BlockStatus; + +typedef struct +{ + UINT32 sectorNumber; + UINT16* ptrBuffer; + BlockStatus status; +} BlockDeviceHandle; + + +*/ + +typedef struct +{ + UINT32 DumpAddressRange; + UINT32 FlashStartAddress; + UINT32 length; + UINT32 Core_ID; +} FilePreamble; + + +typedef void (*pfnDebugLog)(TCHAR* pLogEntry); + +#endif // DOWNLOADER_H + diff --git a/fbfdownloader/src/fbfdownload.h b/fbfdownloader/src/fbfdownload.h new file mode 100644 index 00000000..598188a5 --- /dev/null +++ b/fbfdownloader/src/fbfdownload.h @@ -0,0 +1,22 @@ +#ifndef FBF_H +#define FBF_H + +#include +#include + +//return 0 SUCCRSS +//return 1 FAIL +//timeout 0 Infinite Wait +//timeout >0 Wait N seconds for Download +#ifdef __cplusplus +extern "C"{ +#endif +int fbfdownload(char * strBinFilePath, int timeout); + +#ifdef __cplusplus +} +#endif + + + +#endif diff --git a/fbfdownloader/src/khash.h b/fbfdownloader/src/khash.h new file mode 100644 index 00000000..cfafeab9 --- /dev/null +++ b/fbfdownloader/src/khash.h @@ -0,0 +1,627 @@ +/* The MIT License + + Copyright (c) 2008, 2009, 2011 by Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +/* + An example: + +#include "khash.h" +KHASH_MAP_INIT_INT(32, char) +int main() { + int ret, is_missing; + khiter_t k; + khash_t(32) *h = kh_init(32); + k = kh_put(32, h, 5, &ret); + kh_value(h, k) = 10; + k = kh_get(32, h, 10); + is_missing = (k == kh_end(h)); + k = kh_get(32, h, 5); + kh_del(32, h, k); + for (k = kh_begin(h); k != kh_end(h); ++k) + if (kh_exist(h, k)) kh_value(h, k) = 1; + kh_destroy(32, h); + return 0; +} +*/ + +/* + 2013-05-02 (0.2.8): + + * Use quadratic probing. When the capacity is power of 2, stepping function + i*(i+1)/2 guarantees to traverse each bucket. It is better than double + hashing on cache performance and is more robust than linear probing. + + In theory, double hashing should be more robust than quadratic probing. + However, my implementation is probably not for large hash tables, because + the second hash function is closely tied to the first hash function, + which reduce the effectiveness of double hashing. + + Reference: http://research.cs.vt.edu/AVresearch/hashing/quadratic.php + + 2011-12-29 (0.2.7): + + * Minor code clean up; no actual effect. + + 2011-09-16 (0.2.6): + + * The capacity is a power of 2. This seems to dramatically improve the + speed for simple keys. Thank Zilong Tan for the suggestion. Reference: + + - http://code.google.com/p/ulib/ + - http://nothings.org/computer/judy/ + + * Allow to optionally use linear probing which usually has better + performance for random input. Double hashing is still the default as it + is more robust to certain non-random input. + + * Added Wang's integer hash function (not used by default). This hash + function is more robust to certain non-random input. + + 2011-02-14 (0.2.5): + + * Allow to declare global functions. + + 2009-09-26 (0.2.4): + + * Improve portability + + 2008-09-19 (0.2.3): + + * Corrected the example + * Improved interfaces + + 2008-09-11 (0.2.2): + + * Improved speed a little in kh_put() + + 2008-09-10 (0.2.1): + + * Added kh_clear() + * Fixed a compiling error + + 2008-09-02 (0.2.0): + + * Changed to token concatenation which increases flexibility. + + 2008-08-31 (0.1.2): + + * Fixed a bug in kh_get(), which has not been tested previously. + + 2008-08-31 (0.1.1): + + * Added destructor +*/ + + +#ifndef __AC_KHASH_H +#define __AC_KHASH_H + +/*! + @header + + Generic hash table library. + */ + +#define AC_VERSION_KHASH_H "0.2.8" + +#include +#include +#include + +/* compiler specific configuration */ + +#if UINT_MAX == 0xffffffffu +typedef unsigned int khint32_t; +#elif ULONG_MAX == 0xffffffffu +typedef unsigned long khint32_t; +#endif + +#if ULONG_MAX == ULLONG_MAX +typedef unsigned long khint64_t; +#else +typedef unsigned long long khint64_t; +#endif + +#ifndef kh_inline +#ifdef _MSC_VER +#define kh_inline __inline +#else +#define kh_inline inline +#endif +#endif /* kh_inline */ + +#ifndef klib_unused +#if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3) +#define klib_unused __attribute__ ((__unused__)) +#else +#define klib_unused +#endif +#endif /* klib_unused */ + +typedef khint32_t khint_t; +typedef khint_t khiter_t; + +#define __ac_isempty(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&2) +#define __ac_isdel(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&1) +#define __ac_iseither(flag, i) ((flag[i>>4]>>((i&0xfU)<<1))&3) +#define __ac_set_isdel_false(flag, i) (flag[i>>4]&=~(1ul<<((i&0xfU)<<1))) +#define __ac_set_isempty_false(flag, i) (flag[i>>4]&=~(2ul<<((i&0xfU)<<1))) +#define __ac_set_isboth_false(flag, i) (flag[i>>4]&=~(3ul<<((i&0xfU)<<1))) +#define __ac_set_isdel_true(flag, i) (flag[i>>4]|=1ul<<((i&0xfU)<<1)) + +#define __ac_fsize(m) ((m) < 16? 1 : (m)>>4) + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#ifndef kcalloc +#define kcalloc(N,Z) calloc(N,Z) +#endif +#ifndef kmalloc +#define kmalloc(Z) malloc(Z) +#endif +#ifndef krealloc +#define krealloc(P,Z) realloc(P,Z) +#endif +#ifndef kfree +#define kfree(P) free(P) +#endif + +static const double __ac_HASH_UPPER = 0.77; + +#define __KHASH_TYPE(name, khkey_t, khval_t) \ + typedef struct kh_##name##_s { \ + khint_t n_buckets, size, n_occupied, upper_bound; \ + khint32_t *flags; \ + khkey_t *keys; \ + khval_t *vals; \ + } kh_##name##_t; + +#define __KHASH_PROTOTYPES(name, khkey_t, khval_t) \ + extern kh_##name##_t *kh_init_##name(void); \ + extern void kh_destroy_##name(kh_##name##_t *h); \ + extern void kh_clear_##name(kh_##name##_t *h); \ + extern khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key); \ + extern int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ + extern khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret); \ + extern void kh_del_##name(kh_##name##_t *h, khint_t x); + +#define __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + SCOPE kh_##name##_t *kh_init_##name(void) { \ + return (kh_##name##_t*)kcalloc(1, sizeof(kh_##name##_t)); \ + } \ + SCOPE void kh_destroy_##name(kh_##name##_t *h) \ + { \ + if (h) { \ + kfree((void *)h->keys); kfree(h->flags); \ + kfree((void *)h->vals); \ + kfree(h); \ + } \ + } \ + SCOPE void kh_clear_##name(kh_##name##_t *h) \ + { \ + if (h && h->flags) { \ + memset(h->flags, 0xaa, __ac_fsize(h->n_buckets) * sizeof(khint32_t)); \ + h->size = h->n_occupied = 0; \ + } \ + } \ + SCOPE khint_t kh_get_##name(const kh_##name##_t *h, khkey_t key) \ + { \ + if (h->n_buckets) { \ + khint_t k, i, last, mask, step = 0; \ + mask = h->n_buckets - 1; \ + k = __hash_func(key); i = k & mask; \ + last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + i = (i + (++step)) & mask; \ + if (i == last) return h->n_buckets; \ + } \ + return __ac_iseither(h->flags, i)? h->n_buckets : i; \ + } else return 0; \ + } \ + SCOPE int kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets) \ + { /* This function uses 0.25*n_buckets bytes of working space instead of [sizeof(key_t+val_t)+.25]*n_buckets. */ \ + khint32_t *new_flags = 0; \ + khint_t j = 1; \ + { \ + kroundup32(new_n_buckets); \ + if (new_n_buckets < 4) new_n_buckets = 4; \ + if (h->size >= (khint_t)(new_n_buckets * __ac_HASH_UPPER + 0.5)) j = 0; /* requested size is too small */ \ + else { /* hash table size to be changed (shrink or expand); rehash */ \ + new_flags = (khint32_t*)kmalloc(__ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ + if (!new_flags) return -1; \ + memset(new_flags, 0xaa, __ac_fsize(new_n_buckets) * sizeof(khint32_t)); \ + if (h->n_buckets < new_n_buckets) { /* expand */ \ + khkey_t *new_keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (!new_keys) { kfree(new_flags); return -1; } \ + h->keys = new_keys; \ + if (kh_is_map) { \ + khval_t *new_vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ + if (!new_vals) { kfree(new_flags); return -1; } \ + h->vals = new_vals; \ + } \ + } /* otherwise shrink */ \ + } \ + } \ + if (j) { /* rehashing is needed */ \ + for (j = 0; j != h->n_buckets; ++j) { \ + if (__ac_iseither(h->flags, j) == 0) { \ + khkey_t key = h->keys[j]; \ + khval_t val; \ + khint_t new_mask; \ + new_mask = new_n_buckets - 1; \ + if (kh_is_map) val = h->vals[j]; \ + __ac_set_isdel_true(h->flags, j); \ + while (1) { /* kick-out process; sort of like in Cuckoo hashing */ \ + khint_t k, i, step = 0; \ + k = __hash_func(key); \ + i = k & new_mask; \ + while (!__ac_isempty(new_flags, i)) i = (i + (++step)) & new_mask; \ + __ac_set_isempty_false(new_flags, i); \ + if (i < h->n_buckets && __ac_iseither(h->flags, i) == 0) { /* kick out the existing element */ \ + { khkey_t tmp = h->keys[i]; h->keys[i] = key; key = tmp; } \ + if (kh_is_map) { khval_t tmp = h->vals[i]; h->vals[i] = val; val = tmp; } \ + __ac_set_isdel_true(h->flags, i); /* mark it as deleted in the old hash table */ \ + } else { /* write the element and jump out of the loop */ \ + h->keys[i] = key; \ + if (kh_is_map) h->vals[i] = val; \ + break; \ + } \ + } \ + } \ + } \ + if (h->n_buckets > new_n_buckets) { /* shrink the hash table */ \ + h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \ + if (kh_is_map) h->vals = (khval_t*)krealloc((void *)h->vals, new_n_buckets * sizeof(khval_t)); \ + } \ + kfree(h->flags); /* free the working space */ \ + h->flags = new_flags; \ + h->n_buckets = new_n_buckets; \ + h->n_occupied = h->size; \ + h->upper_bound = (khint_t)(h->n_buckets * __ac_HASH_UPPER + 0.5); \ + } \ + return 0; \ + } \ + SCOPE khint_t kh_put_##name(kh_##name##_t *h, khkey_t key, int *ret) \ + { \ + khint_t x; \ + if (h->n_occupied >= h->upper_bound) { /* update the hash table */ \ + if (h->n_buckets > (h->size<<1)) { \ + if (kh_resize_##name(h, h->n_buckets - 1) < 0) { /* clear "deleted" elements */ \ + *ret = -1; return h->n_buckets; \ + } \ + } else if (kh_resize_##name(h, h->n_buckets + 1) < 0) { /* expand the hash table */ \ + *ret = -1; return h->n_buckets; \ + } \ + } /* TODO: to implement automatically shrinking; resize() already support shrinking */ \ + { \ + khint_t k, i, site, last, mask = h->n_buckets - 1, step = 0; \ + x = site = h->n_buckets; k = __hash_func(key); i = k & mask; \ + if (__ac_isempty(h->flags, i)) x = i; /* for speed up */ \ + else { \ + last = i; \ + while (!__ac_isempty(h->flags, i) && (__ac_isdel(h->flags, i) || !__hash_equal(h->keys[i], key))) { \ + if (__ac_isdel(h->flags, i)) site = i; \ + i = (i + (++step)) & mask; \ + if (i == last) { x = site; break; } \ + } \ + if (x == h->n_buckets) { \ + if (__ac_isempty(h->flags, i) && site != h->n_buckets) x = site; \ + else x = i; \ + } \ + } \ + } \ + if (__ac_isempty(h->flags, x)) { /* not present at all */ \ + h->keys[x] = key; \ + __ac_set_isboth_false(h->flags, x); \ + ++h->size; ++h->n_occupied; \ + *ret = 1; \ + } else if (__ac_isdel(h->flags, x)) { /* deleted */ \ + h->keys[x] = key; \ + __ac_set_isboth_false(h->flags, x); \ + ++h->size; \ + *ret = 2; \ + } else *ret = 0; /* Don't touch h->keys[x] if present and not deleted */ \ + return x; \ + } \ + SCOPE void kh_del_##name(kh_##name##_t *h, khint_t x) \ + { \ + if (x != h->n_buckets && !__ac_iseither(h->flags, x)) { \ + __ac_set_isdel_true(h->flags, x); \ + --h->size; \ + } \ + } + +#define KHASH_DECLARE(name, khkey_t, khval_t) \ + __KHASH_TYPE(name, khkey_t, khval_t) \ + __KHASH_PROTOTYPES(name, khkey_t, khval_t) + +#define KHASH_INIT2(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + __KHASH_TYPE(name, khkey_t, khval_t) \ + __KHASH_IMPL(name, SCOPE, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) + +#define KHASH_INIT(name, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) \ + KHASH_INIT2(name, static kh_inline klib_unused, khkey_t, khval_t, kh_is_map, __hash_func, __hash_equal) + +/* --- BEGIN OF HASH FUNCTIONS --- */ + +/*! @function + @abstract Integer hash function + @param key The integer [khint32_t] + @return The hash value [khint_t] + */ +#define kh_int_hash_func(key) (khint32_t)(key) +/*! @function + @abstract Integer comparison function + */ +#define kh_int_hash_equal(a, b) ((a) == (b)) +/*! @function + @abstract 64-bit integer hash function + @param key The integer [khint64_t] + @return The hash value [khint_t] + */ +#define kh_int64_hash_func(key) (khint32_t)((key)>>33^(key)^(key)<<11) +/*! @function + @abstract 64-bit integer comparison function + */ +#define kh_int64_hash_equal(a, b) ((a) == (b)) +/*! @function + @abstract const char* hash function + @param s Pointer to a null terminated string + @return The hash value + */ +static kh_inline khint_t __ac_X31_hash_string(const char *s) +{ + khint_t h = (khint_t)*s; + if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s; + return h; +} +/*! @function + @abstract Another interface to const char* hash function + @param key Pointer to a null terminated string [const char*] + @return The hash value [khint_t] + */ +#define kh_str_hash_func(key) __ac_X31_hash_string(key) +/*! @function + @abstract Const char* comparison function + */ +#define kh_str_hash_equal(a, b) (strcmp(a, b) == 0) + +static kh_inline khint_t __ac_Wang_hash(khint_t key) +{ + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; +} +#define kh_int_hash_func2(key) __ac_Wang_hash((khint_t)key) + +/* --- END OF HASH FUNCTIONS --- */ + +/* Other convenient macros... */ + +/*! + @abstract Type of the hash table. + @param name Name of the hash table [symbol] + */ +#define khash_t(name) kh_##name##_t + +/*! @function + @abstract Initiate a hash table. + @param name Name of the hash table [symbol] + @return Pointer to the hash table [khash_t(name)*] + */ +#define kh_init(name) kh_init_##name() + +/*! @function + @abstract Destroy a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + */ +#define kh_destroy(name, h) kh_destroy_##name(h) + +/*! @function + @abstract Reset a hash table without deallocating memory. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + */ +#define kh_clear(name, h) kh_clear_##name(h) + +/*! @function + @abstract Resize a hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param s New size [khint_t] + */ +#define kh_resize(name, h, s) kh_resize_##name(h, s) + +/*! @function + @abstract Insert a key to the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @param r Extra return code: -1 if the operation failed; + 0 if the key is present in the hash table; + 1 if the bucket is empty (never used); 2 if the element in + the bucket has been deleted [int*] + @return Iterator to the inserted element [khint_t] + */ +#define kh_put(name, h, k, r) kh_put_##name(h, k, r) + +/*! @function + @abstract Retrieve a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Key [type of keys] + @return Iterator to the found element, or kh_end(h) if the element is absent [khint_t] + */ +#define kh_get(name, h, k) kh_get_##name(h, k) + +/*! @function + @abstract Remove a key from the hash table. + @param name Name of the hash table [symbol] + @param h Pointer to the hash table [khash_t(name)*] + @param k Iterator to the element to be deleted [khint_t] + */ +#define kh_del(name, h, k) kh_del_##name(h, k) + +/*! @function + @abstract Test whether a bucket contains data. + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return 1 if containing data; 0 otherwise [int] + */ +#define kh_exist(h, x) (!__ac_iseither((h)->flags, (x))) + +/*! @function + @abstract Get key given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Key [type of keys] + */ +#define kh_key(h, x) ((h)->keys[x]) + +/*! @function + @abstract Get value given an iterator + @param h Pointer to the hash table [khash_t(name)*] + @param x Iterator to the bucket [khint_t] + @return Value [type of values] + @discussion For hash sets, calling this results in segfault. + */ +#define kh_val(h, x) ((h)->vals[x]) + +/*! @function + @abstract Alias of kh_val() + */ +#define kh_value(h, x) ((h)->vals[x]) + +/*! @function + @abstract Get the start iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The start iterator [khint_t] + */ +#define kh_begin(h) (khint_t)(0) + +/*! @function + @abstract Get the end iterator + @param h Pointer to the hash table [khash_t(name)*] + @return The end iterator [khint_t] + */ +#define kh_end(h) ((h)->n_buckets) + +/*! @function + @abstract Get the number of elements in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of elements in the hash table [khint_t] + */ +#define kh_size(h) ((h)->size) + +/*! @function + @abstract Get the number of buckets in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @return Number of buckets in the hash table [khint_t] + */ +#define kh_n_buckets(h) ((h)->n_buckets) + +/*! @function + @abstract Iterate over the entries in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @param kvar Variable to which key will be assigned + @param vvar Variable to which value will be assigned + @param code Block of code to execute + */ +#define kh_foreach(h, kvar, vvar, code) { khint_t __i; \ + for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ + if (!kh_exist(h,__i)) continue; \ + (kvar) = kh_key(h,__i); \ + (vvar) = kh_val(h,__i); \ + code; \ + } } + +/*! @function + @abstract Iterate over the values in the hash table + @param h Pointer to the hash table [khash_t(name)*] + @param vvar Variable to which value will be assigned + @param code Block of code to execute + */ +#define kh_foreach_value(h, vvar, code) { khint_t __i; \ + for (__i = kh_begin(h); __i != kh_end(h); ++__i) { \ + if (!kh_exist(h,__i)) continue; \ + (vvar) = kh_val(h,__i); \ + code; \ + } } + +/* More convenient interfaces */ + +/*! @function + @abstract Instantiate a hash set containing integer keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_INT(name) \ + KHASH_INIT(name, khint32_t, char, 0, kh_int_hash_func, kh_int_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_INT(name, khval_t) \ + KHASH_INIT(name, khint32_t, khval_t, 1, kh_int_hash_func, kh_int_hash_equal) + +/*! @function + @abstract Instantiate a hash set containing 64-bit integer keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_INT64(name) \ + KHASH_INIT(name, khint64_t, char, 0, kh_int64_hash_func, kh_int64_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing 64-bit integer keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_INT64(name, khval_t) \ + KHASH_INIT(name, khint64_t, khval_t, 1, kh_int64_hash_func, kh_int64_hash_equal) + +typedef const char *kh_cstr_t; +/*! @function + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + */ +#define KHASH_SET_INIT_STR(name) \ + KHASH_INIT(name, kh_cstr_t, char, 0, kh_str_hash_func, kh_str_hash_equal) + +/*! @function + @abstract Instantiate a hash map containing const char* keys + @param name Name of the hash table [symbol] + @param khval_t Type of values [type] + */ +#define KHASH_MAP_INIT_STR(name, khval_t) \ + KHASH_INIT(name, kh_cstr_t, khval_t, 1, kh_str_hash_func, kh_str_hash_equal) + +#endif /* __AC_KHASH_H */ diff --git a/fbfdownloader/src/klist.h b/fbfdownloader/src/klist.h new file mode 100644 index 00000000..09a94bfa --- /dev/null +++ b/fbfdownloader/src/klist.h @@ -0,0 +1,169 @@ +/* The MIT License + + Copyright (c) 2008-2009, by Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#ifndef _AC_KLIST_H +#define _AC_KLIST_H + +#include + +#ifndef klib_unused +#if (defined __clang__ && __clang_major__ >= 3) || (defined __GNUC__ && __GNUC__ >= 3) +#define klib_unused __attribute__ ((__unused__)) +#else +#define klib_unused +#endif +#endif /* klib_unused */ + +#define KMEMPOOL_INIT2(SCOPE, name, kmptype_t, kmpfree_f) \ + typedef struct { \ + size_t cnt, n, max; \ + kmptype_t **buf; \ + } kmp_##name##_t; \ + SCOPE kmp_##name##_t *kmp_init_##name(void) { \ + return (kmp_##name##_t *)calloc(1, sizeof(kmp_##name##_t)); \ + } \ + SCOPE void kmp_destroy_##name(kmp_##name##_t *mp) { \ + size_t k; \ + for (k = 0; k < mp->n; ++k) { \ + kmpfree_f(mp->buf[k]); free(mp->buf[k]); \ + } \ + free(mp->buf); free(mp); \ + } \ + SCOPE kmptype_t *kmp_alloc_##name(kmp_##name##_t *mp) { \ + ++mp->cnt; \ + if (mp->n == 0) return (kmptype_t *)calloc(1, sizeof(kmptype_t)); \ + return mp->buf[--mp->n]; \ + } \ + SCOPE void kmp_free_##name(kmp_##name##_t *mp, kmptype_t *p) { \ + --mp->cnt; \ + if (mp->n == mp->max) { \ + mp->max = mp->max? mp->max<<1 : 16; \ + mp->buf = (kmptype_t **)realloc(mp->buf, sizeof(kmptype_t *) * mp->max); \ + } \ + mp->buf[mp->n++] = p; \ + } + +#define KMEMPOOL_INIT(name, kmptype_t, kmpfree_f) \ + KMEMPOOL_INIT2(static inline klib_unused, name, kmptype_t, kmpfree_f) + +#define kmempool_t(name) kmp_##name##_t +#define kmp_init(name) kmp_init_##name() +#define kmp_destroy(name, mp) kmp_destroy_##name(mp) +#define kmp_alloc(name, mp) kmp_alloc_##name(mp) +#define kmp_free(name, mp, p) kmp_free_##name(mp, p) + +#define KLIST_INIT2(SCOPE, name, kltype_t, kmpfree_t) \ + struct __kl1_##name { \ + kltype_t data; \ + struct __kl1_##name *next; \ + }; \ + typedef struct __kl1_##name kl1_##name; \ + KMEMPOOL_INIT2(SCOPE, name, kl1_##name, kmpfree_t) \ + typedef struct { \ + kl1_##name *head, *tail; \ + kmp_##name##_t *mp; \ + size_t size; \ + } kl_##name##_t; \ + SCOPE kl_##name##_t *kl_init_##name(void) { \ + kl_##name##_t *kl = (kl_##name##_t *)calloc(1, sizeof(kl_##name##_t)); \ + kl->mp = kmp_init(name); \ + kl->head = kl->tail = kmp_alloc(name, kl->mp); \ + kl->head->next = 0; \ + return kl; \ + } \ + SCOPE void kl_destroy_##name(kl_##name##_t *kl) { \ + kl1_##name *p; \ + if (kl == NULL) return; \ + for (p = kl->head; p != kl->tail; p = p->next) \ + kmp_free(name, kl->mp, p); \ + kmp_free(name, kl->mp, p); \ + kmp_destroy(name, kl->mp); \ + free(kl);kl=NULL; \ + } \ + SCOPE kltype_t *kl_pushp_##name(kl_##name##_t *kl) { \ + kl1_##name *q, *p = kmp_alloc(name, kl->mp); \ + q = kl->tail; p->next = 0; kl->tail->next = p; kl->tail = p; \ + ++kl->size; \ + return &q->data; \ + } \ + SCOPE kltype_t *kl_pushf_##name(kl_##name##_t *kl) { \ + kl1_##name *q, *p = kmp_alloc(name, kl->mp); \ + p->next = kl->head; kl->head = p; \ + ++kl->size; \ + return &p->data; \ + } \ + SCOPE kltype_t *kl_back_##name(kl_##name##_t *kl) { \ + kl1_##name *p = kl->head; \ + while (p->next != kl->tail) {p = p->next;} \ + return &p->data; \ + } \ + SCOPE int kl_shift_##name(kl_##name##_t *kl, kltype_t *d) { \ + kl1_##name *p; \ + if (kl->head->next == 0) return -1; \ + --kl->size; \ + p = kl->head; kl->head = kl->head->next; \ + if (d) *d = p->data; \ + kmp_free(name, kl->mp, p); \ + return 0; \ + } \ + SCOPE int kl_erase_##name(kl_##name##_t *kl, kl1_##name **pp) { \ + kl1_##name *p = *pp; \ + if (kl->head->next == 0) return -1; \ + if (p == kl->head) return kl_shift_##name(kl,0); \ + --kl->size; \ + for (kl1_##name *iter=kl->head;iter!=kl->tail;iter=iter->next) \ + if (p == iter->next){iter->next = p->next; \ + kmp_free(name, kl->mp, p);*pp=iter;break;} \ + return 0; \ + } \ + SCOPE size_t kl_size_##name(kl_##name##_t *kl){ \ + return kl->size;} \ + SCOPE void kl_clear_##name(kl_##name##_t *kl){ \ + while(kl_shift_##name(kl,0) != -1){}} + + + +#define KLIST_INIT(name, kltype_t, kmpfree_t) \ + KLIST_INIT2(static inline klib_unused, name, kltype_t, kmpfree_t) + +#define kliter_t(name) kl1_##name +#define klist_t(name) kl_##name##_t +#define kl_val(iter) ((iter)->data) +#define kl_next(iter) ((iter)->next) +#define kl_begin(kl) ((kl)->head) +#define kl_end(kl) ((kl)->tail) + +#define kl_init(name) kl_init_##name() +#define kl_destroy(name, kl) kl_destroy_##name(kl) +#define kl_pushp(name, kl) kl_pushp_##name(kl) +#define kl_pushf(name, kl) kl_pushf_##name(kl) +#define kl_back(name, kl) kl_back_##name(kl) +#define kl_shift(name, kl, d) kl_shift_##name(kl, d) +#define kl_erase(name, kl, pp) kl_erase_##name(kl, pp) +#define kl_size(name, kl) kl_size_##name(kl) +#define kl_clear(name, kl) kl_clear_##name(kl) + + +#endif diff --git a/fbfdownloader/src/kstring.c b/fbfdownloader/src/kstring.c new file mode 100644 index 00000000..262df91d --- /dev/null +++ b/fbfdownloader/src/kstring.c @@ -0,0 +1,294 @@ +#include +#include +#include +#include +#include +#include "kstring.h" + +int kvsprintf(kstring_t *s, const char *fmt, va_list ap) +{ + va_list args; + int l; + va_copy(args, ap); + l = vsnprintf(s->s + s->l, s->m - s->l, fmt, args); // This line does not work with glibc 2.0. See `man snprintf'. + va_end(args); + if (l + 1 > s->m - s->l) { + s->m = s->l + l + 2; + kroundup32(s->m); + s->s = (char*)realloc(s->s, s->m); + va_copy(args, ap); + l = vsnprintf(s->s + s->l, s->m - s->l, fmt, args); + va_end(args); + } + s->l += l; + return l; +} + +int ksprintf(kstring_t *s, const char *fmt, ...) +{ + va_list ap; + int l; + va_start(ap, fmt); + l = kvsprintf(s, fmt, ap); + va_end(ap); + return l; +} + +char *kstrtok(const char *str, const char *sep_in, ks_tokaux_t *aux) +{ + const unsigned char *p, *start, *sep = (unsigned char *) sep_in; + if (sep) { // set up the table + if (str == 0 && aux->finished) return 0; // no need to set up if we have finished + aux->finished = 0; + if (sep[0] && sep[1]) { + aux->sep = -1; + aux->tab[0] = aux->tab[1] = aux->tab[2] = aux->tab[3] = 0; + for (p = sep; *p; ++p) aux->tab[*p>>6] |= 1ull<<(*p&0x3f); + } else aux->sep = sep[0]; + } + if (aux->finished) return 0; + else if (str) start = (unsigned char *) str, aux->finished = 0; + else start = (unsigned char *) aux->p + 1; + if (aux->sep < 0) { + for (p = start; *p; ++p) + if (aux->tab[*p>>6]>>(*p&0x3f)&1) break; + } else { + for (p = start; *p; ++p) + if (*p == aux->sep) break; + } + aux->p = (const char *) p; // end of token + if (*p == 0) aux->finished = 1; // no more tokens + return (char*)start; +} + +// s MUST BE a null terminated string; l = strlen(s) +int ksplit_core(char *s, int delimiter, int *_max, int **_offsets) +{ + int i, n, max, last_char, last_start, *offsets, l; + n = 0; max = *_max; offsets = *_offsets; + l = strlen(s); + +#define __ksplit_aux do { \ + if (_offsets) { \ + s[i] = 0; \ + if (n == max) { \ + int *tmp; \ + max = max? max<<1 : 2; \ + if ((tmp = (int*)realloc(offsets, sizeof(int) * max))) { \ + offsets = tmp; \ + } else { \ + free(offsets); \ + *_offsets = NULL; \ + return 0; \ + } \ + } \ + offsets[n++] = last_start; \ + } else ++n; \ + } while (0) + + for (i = 0, last_char = last_start = 0; i <= l; ++i) { + if (delimiter == 0) { + if (isspace(s[i]) || s[i] == 0) { + if (isgraph(last_char)) __ksplit_aux; // the end of a field + } else { + if (isspace(last_char) || last_char == 0) last_start = i; + } + } else { + if (s[i] == delimiter || s[i] == 0) { + if (last_char != 0 && last_char != delimiter) __ksplit_aux; // the end of a field + } else { + if (last_char == delimiter || last_char == 0) last_start = i; + } + } + last_char = s[i]; + } + *_max = max; *_offsets = offsets; + return n; +} + +int kgetline(kstring_t *s, kgets_func *fgets_fn, void *fp) +{ + size_t l0 = s->l; + + while (s->l == l0 || s->s[s->l-1] != '\n') { + if (s->m - s->l < 200) ks_resize(s, s->m + 200); + if (fgets_fn(s->s + s->l, s->m - s->l, fp) == NULL) break; + s->l += strlen(s->s + s->l); + } + + if (s->l == l0) return EOF; + + if (s->l > l0 && s->s[s->l-1] == '\n') { + s->l--; + if (s->l > l0 && s->s[s->l-1] == '\r') s->l--; + } + s->s[s->l] = '\0'; + return 0; +} + +/********************** + * Boyer-Moore search * + **********************/ + +typedef unsigned char ubyte_t; + +// reference: http://www-igm.univ-mlv.fr/~lecroq/string/node14.html +static int *ksBM_prep(const ubyte_t *pat, int m) +{ + int i, *suff, *prep, *bmGs, *bmBc; + prep = (int*)calloc(m + 256, sizeof(int)); + bmGs = prep; bmBc = prep + m; + { // preBmBc() + for (i = 0; i < 256; ++i) bmBc[i] = m; + for (i = 0; i < m - 1; ++i) bmBc[pat[i]] = m - i - 1; + } + suff = (int*)calloc(m, sizeof(int)); + { // suffixes() + int f = 0, g; + suff[m - 1] = m; + g = m - 1; + for (i = m - 2; i >= 0; --i) { + if (i > g && suff[i + m - 1 - f] < i - g) + suff[i] = suff[i + m - 1 - f]; + else { + if (i < g) g = i; + f = i; + while (g >= 0 && pat[g] == pat[g + m - 1 - f]) --g; + suff[i] = f - g; + } + } + } + { // preBmGs() + int j = 0; + for (i = 0; i < m; ++i) bmGs[i] = m; + for (i = m - 1; i >= 0; --i) + if (suff[i] == i + 1) + for (; j < m - 1 - i; ++j) + if (bmGs[j] == m) + bmGs[j] = m - 1 - i; + for (i = 0; i <= m - 2; ++i) + bmGs[m - 1 - suff[i]] = m - 1 - i; + } + free(suff); + return prep; +} + +void *kmemmem(const void *_str, int n, const void *_pat, int m, int **_prep) +{ + int i, j, *prep = 0, *bmGs, *bmBc; + const ubyte_t *str, *pat; + str = (const ubyte_t*)_str; pat = (const ubyte_t*)_pat; + prep = (_prep == 0 || *_prep == 0)? ksBM_prep(pat, m) : *_prep; + if (_prep && *_prep == 0) *_prep = prep; + bmGs = prep; bmBc = prep + m; + j = 0; + while (j <= n - m) { + for (i = m - 1; i >= 0 && pat[i] == str[i+j]; --i); + if (i >= 0) { + int max = bmBc[str[i+j]] - m + 1 + i; + if (max < bmGs[i]) max = bmGs[i]; + j += max; + } else return (void*)(str + j); + } + if (_prep == 0) free(prep); + return 0; +} + +char *kstrstr(const char *str, const char *pat, int **_prep) +{ + return (char*)kmemmem(str, strlen(str), pat, strlen(pat), _prep); +} + +char *kstrnstr(const char *str, const char *pat, int n, int **_prep) +{ + return (char*)kmemmem(str, n, pat, strlen(pat), _prep); +} + +void kstrcpy(kstring_t *s, const char *src) +{ + const char *buf = strdup(src); + if (s->s) + free(s->s); + ks_release(s); + kputs(buf, s); + free((void*)buf); + return; +} + + +/*********************** + * The main() function * + ***********************/ + +#ifdef KSTRING_MAIN +#include + +char* WtptpDownLoad_replace_all(char* str,const char* old_value,const char* new_value) +{ + char buf[256]={0}; + char *p = NULL,*pstr = str; + int lo = strlen(old_value); + p = strstr(pstr, old_value); + while (p) + { + strncat(buf, pstr, p-pstr); + strcat(buf, new_value); + pstr = p + lo; + p = strstr(pstr,old_value); + } + strcat(buf,pstr); + strcpy(str, buf); + return str; +} +typedef const char* t_conststr; + +int main() +{ + kstring_t *s; + t_conststr a,b; + int *fields, n, i; + ks_tokaux_t aux; + char *p; + char buf[256] = "asdhesdafhehew"; + a = "abc"; + b = "bcd"; + s = (kstring_t*)calloc(1, sizeof(kstring_t)); + // test ksprintf() + ksprintf(s, "abcdefg:%d", 100); + printf("'%s'\n", s->s); + kputs("hehe ",s); + printf("%s\n", s->s); + + ksprintf(s, "abc%sdefg:", "hehehe"); + printf("!!!!%s\n", s->s); + // test ksplit() + fields = ksplit(s, 0, &n); + for (i = 0; i < n; ++i) + printf("field[%d] = '%s'\n", i, s->s + fields[i]); + kstrcpy(s,s->s+fields[0]); + printf("@@@%s\n", s->s); + printf("replace:%s\n",WtptpDownLoad_replace_all(buf,"he","hello")); + // test kstrtok() + s->l = 0; + for (p = kstrtok("ab:cde:fg/hij::k", ":/", &aux); p; p = kstrtok(0, 0, &aux)) { + kputsn(p, aux.p - p, s); + kputc('\n', s); + } + printf("%s", s->s); + // free + free(s->s); free(s); free(fields); + + { + static char *str = "abcdefgcdgcagtcakcdcd"; + static char *pat = "cd"; + char *ret, *s = str; + int *prep = 0; + while ((ret = kstrstr(s, pat, &prep)) != 0) { + printf("match: %s\n", ret); + s = ret + prep[0]; + } + free(prep); + } + return 0; +} +#endif diff --git a/fbfdownloader/src/kstring.h b/fbfdownloader/src/kstring.h new file mode 100644 index 00000000..f14226ee --- /dev/null +++ b/fbfdownloader/src/kstring.h @@ -0,0 +1,278 @@ +/* The MIT License + + Copyright (c) by Attractive Chaos + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#ifndef KSTRING_H +#define KSTRING_H + +#include +#include +#include +#include +#include + +#ifndef kroundup32 +#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x)) +#endif + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +#define KS_ATTR_PRINTF(fmt, arg) __attribute__((__format__ (__printf__, fmt, arg))) +#else +#define KS_ATTR_PRINTF(fmt, arg) +#endif + + +/* kstring_t is a simple non-opaque type whose fields are likely to be + * used directly by user code (but see also ks_str() and ks_len() below). + * A kstring_t object is initialised by either of + * kstring_t str = { 0, 0, NULL }; + * kstring_t str; ...; str.l = str.m = 0; str.s = NULL; + * and either ownership of the underlying buffer should be given away before + * the object disappears (see ks_release() below) or the kstring_t should be + * destroyed with free(str.s); */ +#ifndef KSTRING_T +#define KSTRING_T kstring_t +typedef struct __kstring_t { + size_t l, m; + char *s; +} kstring_t; +#endif + +typedef struct { + uint64_t tab[4]; + int sep, finished; + const char *p; // end of the current token +} ks_tokaux_t; + +#ifdef __cplusplus +extern "C" { +#endif + + int kvsprintf(kstring_t *s, const char *fmt, va_list ap) KS_ATTR_PRINTF(2,0); + int ksprintf(kstring_t *s, const char *fmt, ...) KS_ATTR_PRINTF(2,3); + int ksplit_core(char *s, int delimiter, int *_max, int **_offsets); + char *kstrstr(const char *str, const char *pat, int **_prep); + char *kstrnstr(const char *str, const char *pat, int n, int **_prep); + void *kmemmem(const void *_str, int n, const void *_pat, int m, int **_prep); + void kstrcpy(kstring_t *s, const char *src); + + /* kstrtok() is similar to strtok_r() except that str is not + * modified and both str and sep can be NULL. For efficiency, it is + * actually recommended to set both to NULL in the subsequent calls + * if sep is not changed. */ + char *kstrtok(const char *str, const char *sep, ks_tokaux_t *aux); + + /* kgetline() uses the supplied fgets()-like function to read a "\n"- + * or "\r\n"-terminated line from fp. The line read is appended to the + * kstring without its terminator and 0 is returned; EOF is returned at + * EOF or on error (determined by querying fp, as per fgets()). */ + typedef char *kgets_func(char *, int, void *); + int kgetline(kstring_t *s, kgets_func *fgets, void *fp); + +#ifdef __cplusplus +} +#endif + +static inline int ks_resize(kstring_t *s, size_t size) +{ + if (s->m < size) { + char *tmp; + s->m = size; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return -1; + } + return 0; +} + +static inline char *ks_str(kstring_t *s) +{ + return s->s; +} + +static inline size_t ks_len(kstring_t *s) +{ + return s->l; +} + +// Give ownership of the underlying buffer away to something else (making +// that something else responsible for freeing it), leaving the kstring_t +// empty and ready to be used again, or ready to go out of scope without +// needing free(str.s) to prevent a memory leak. +static inline char *ks_release(kstring_t *s) +{ + char *ss = s->s; + s->l = s->m = 0; + s->s = NULL; + return ss; +} + +static inline int kputsn(const char *p, int l, kstring_t *s) +{ + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + memcpy(s->s + s->l, p, l); + s->l += l; + s->s[s->l] = 0; + return l; +} + +static inline int kputs(const char *p, kstring_t *s) +{ + return kputsn(p, strlen(p), s); +} + +static inline int kputc(int c, kstring_t *s) +{ + if (s->l + 1 >= s->m) { + char *tmp; + s->m = s->l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + s->s[s->l++] = c; + s->s[s->l] = 0; + return c; +} + +static inline int kputc_(int c, kstring_t *s) +{ + if (s->l + 1 > s->m) { + char *tmp; + s->m = s->l + 1; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + s->s[s->l++] = c; + return 1; +} + +static inline int kputsn_(const void *p, int l, kstring_t *s) +{ + if (s->l + l > s->m) { + char *tmp; + s->m = s->l + l; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + memcpy(s->s + s->l, p, l); + s->l += l; + return l; +} + +static inline int kputw(int c, kstring_t *s) +{ + char buf[16]; + int i, l = 0; + unsigned int x = c; + if (c < 0) x = -x; + do { buf[l++] = x%10 + '0'; x /= 10; } while (x > 0); + if (c < 0) buf[l++] = '-'; + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; + s->s[s->l] = 0; + return 0; +} + +static inline int kputuw(unsigned c, kstring_t *s) +{ + char buf[16]; + int l, i; + unsigned x; + if (c == 0) return kputc('0', s); + for (l = 0, x = c; x > 0; x /= 10) buf[l++] = x%10 + '0'; + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; + s->s[s->l] = 0; + return 0; +} + +static inline int kputl(long c, kstring_t *s) +{ + char buf[32]; + int i, l = 0; + unsigned long x = c; + if (c < 0) x = -x; + do { buf[l++] = x%10 + '0'; x /= 10; } while (x > 0); + if (c < 0) buf[l++] = '-'; + if (s->l + l + 1 >= s->m) { + char *tmp; + s->m = s->l + l + 2; + kroundup32(s->m); + if ((tmp = (char*)realloc(s->s, s->m))) + s->s = tmp; + else + return EOF; + } + for (i = l - 1; i >= 0; --i) s->s[s->l++] = buf[i]; + s->s[s->l] = 0; + return 0; +} + +/* + * Returns 's' split by delimiter, with *n being the number of components; + * NULL on failue. + */ +static inline int *ksplit(kstring_t *s, int delimiter, int *n) +{ + int max = 0, *offsets = 0; + *n = ksplit_core(s->s, delimiter, &max, &offsets); + return offsets; +} + +#endif diff --git a/fbfdownloader/src/libmakefile b/fbfdownloader/src/libmakefile new file mode 100644 index 00000000..c9781ea1 --- /dev/null +++ b/fbfdownloader/src/libmakefile @@ -0,0 +1,49 @@ +############################################################### +# Makefile for the Marvell download for MMP2/wukong/NEVO. +# +# +############################################################## + +CC = gcc +AR = ar +RM = rm +CP = cp +ECHO = echo +TARGET = libfbfdown.a +include tool.mak #makefile +BASE:=$(shell pwd) +LIBS = -lpthread +INCLUDES = -I./ +CCFLAGS += -O2 $(INCLUDES) -D LINUX=1 -D _FILE_OFFSET_BITS=64 -D WINDOWS=0 -D DEBUG_MODE=0 -D TRUSTED_BOOT=1 -D IFLSWD_STATIC -D STATICLIB_FBFDOWNLOAD -D PRINTLOG=1 -g -std=c99 + + +TBBOBJS =CommonFun.o\ + ParaDefine.o\ + WTPCOMMCLASS.o \ + BinFileWtp.o\ + WtptpDownloader.o \ + WtptpDownLoad.o\ + ConvetEdian.o\ + BulkDevNonDrv_Linux.o\ + kstring.o\ + FBFDownloader.o\ + + +OBJS = $(TBBOBJS) + +all:$(TARGET) +$(TARGET):$(OBJS) $(LIBS) -ldl + $(BUILD_LIBRARY) + + +$(TBBOBJS): %.o: ./%.c + $(CC) -c $(CCFLAGS) -I./ -c "./$*.c" -o "$(BASE)/$*.o" +.PHONY: clean +clean: + -rm *.o + + + + + + diff --git a/fbfdownloader/src/libmakefile_cross b/fbfdownloader/src/libmakefile_cross new file mode 100644 index 00000000..c72896fb --- /dev/null +++ b/fbfdownloader/src/libmakefile_cross @@ -0,0 +1,56 @@ +############################################################### +# Makefile for the Marvell download for MMP2/wukong/NEVO. +# +# +############################################################## + +#CC = arm_1103_le-g++ +#CC = mipsel-linux-uclibc-g++ +#CC = mipsel-openwrt-linux-g++ +#CC = arm-hisiv200-linux-gnueabi-g++ +CC = ${CROSS}gcc +AR = ar +RM = rm +CP = cp +ECHO = echo +TARGET = libfbfdown_cross.a +include tool.mak #包含子makefile +BASE:=$(shell pwd) +LIBS = -lpthread +INCLUDES = -I./ +CCFLAGS += -O2 $(INCLUDES) -D LINUX=1 -D WINDOWS=0 -D DEBUG_MODE=0 -D TRUSTED_BOOT=1 -D IFLSWD_STATIC -D STATICLIB_FBFDOWNLOAD -D PRINTLOG=1 -std=c99 + +ifneq ($(ANDROIDBLD),1) +CCFLAGS += -D _FILE_OFFSET_BITS=64 +endif + +TBBOBJS =CommonFun.o\ + ParaDefine.o\ + WTPCOMMCLASS.o \ + BinFileWtp.o\ + kstring.o\ + WtptpDownloader.o \ + WtptpDownLoad.o\ + ConvetEdian.o\ + BulkDevNonDrv_Linux.o\ + FBFDownloader.o\ + + +OBJS = $(TBBOBJS) + +all:$(TARGET) +$(TARGET):$(OBJS) $(LIBS) -ldl + $(BUILD_LIBRARY) + + +$(TBBOBJS): %.o: ./%.c + $(CC) -c $(CCFLAGS) -I./ -c "./$*.c" -o "$(BASE)/$*.o" +.PHONY: clean +clean: + -rm *.o + + + + + + diff --git a/fbfdownloader/src/源码说明.txt b/fbfdownloader/src/源码说明.txt new file mode 100644 index 00000000..c2c8d982 --- /dev/null +++ b/fbfdownloader/src/源码说明.txt @@ -0,0 +1,72 @@ +交叉编译方法 +以使用buildroot-gcc463交叉编译工具链为例: +gcc bin文件路径为: +/home/toolchain/buildroot-gcc463/usr/bin/mipsel-linux-gcc +export CROSS=/home/toolchain/buildroot-gcc463/usr/bin/mipsel-linux- +cd 源码目录 +make -f FBFDownloader_makefile_cross +对于一些toolchain,需要: +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/toolchain/buildroot-gcc463/usr/lib + +生成的fbfdownloader_cross即为下载工具。 + +程序入口为:FBFDownloader.c:728 main(int argc, char *argv[]) + +FBFDownloader.c:732 ParseCommandLine为解析参数函数,包括 -b BinFile.bin(必选) +-p logFilePath(可选,指定下载过程中log和临时文件生成的目录) + +FBFDownloader.c:780 PInstanceParams lpInstanceParam. 该结构体存放下载相关的参数 + +FBFDownloader.c:790-800 该过程为从BinFile.bin文件中提取下载相关参数。 + +FBFDownloader.c:813 执行下载过程函数InitializeBL(lpInstanceParam) +WtptpDownLoad.c:6 InitializeBL(PInstanceParams pInstParam) +WtptpDownloader.c:2762 BOOL WtptpDownLoad_InitializeBL(struct CWtptpDownLoad *me,PInstanceParams pInstParam) +WtptpDownloader.c:2867-2892 下载前参数解析准备过程。 +WtptpDownloader.c:2901 创建设备检测线程,检测下载口枚举 +WtptpDownloader.c:535 PVOID WtptpDownLoad_WtptpDeviceDetectThread(PVOID Arg) +WtptpDownloader.c:541 WtptpDownLoad_init_hotplug_sock 创建socket,用来检测下载设备hotplug +WtptpDownloader.c:542 BulkDevNonDrv_FindAllSupportedDevices 检测已经接入的下载设备,根据设备的PID和VID判断是否为下载设备 +WtptpDownloader.c:554 下载设备已经存在,打开设备WtptpDownLoad_WtptpOpenDevice +WtptpDownloader.c:581 BulkDevNonDrv_CheckDevForNetLink 检测到下载设备插拔事件 + WtptpDownloader.c:590 设备插入 打开设备 WtptpDownLoad_WtptpOpenDevice + WtptpDownloader.c:610 设备移除 停止下载流程 WtptpDownLoad_SetAndWaitForThreadExit + +打开设备 +WtptpDownloader.c:482 void WtptpDownLoad_WtptpOpenDevice(struct CWtptpDownLoad *me,struct CWtptpDownLoad *pWtptpDownLoad, USB_HANDLE *pLinuxUsb) + WtptpDownloader.c:492-507准备工作,根据设备路径创建Log文件 + WtptpDownloader.c:509 打开设备函数WtptpDownLoad_OpenDevice +WtptpDownloader.c:916 BOOL WtptpDownLoad_OpenDevice(struct CWtptpDownLoad *me,PDEVICE pDev) + WtptpDownloader.c:954 WtptpDownLoad_GetDeviceBootType 获取设备型号和类型,(BootRom,BootLoader) + 该过程主要流程为: + 1、打开USB口 WtptpDownloader.c:725 OpenUsbPort + 2、与芯片进行握手,发送Preamble消息 WtptpDownloader.c:736 SendPreamble + 3、获取芯片当前状态 WtptpDownloader.c:747 GetTargetMessage + 4、发送GetVersion消息,获取芯片型号和类型,WtptpDownloader.c:764 GetVersion + 5、处理GetVersion返回的内容,WtptpDownloader.c:769-912 + 如果设备类型为BootRom,即模块为空板,则创建BootRom下载线程。WtptpDownloader.c:971-988 + BootRom下载(空板下载、ForceDownload)是将OBM下载至模块DDR中,下载完成后,当前BootROM设备会自动移除,随后模块以BootLoader类型接入大板(Host),工具会再次检测到设备接入,且其类型为BootLoader。 + 如果设备类型为BootLoader,即非空板,则创建BootLoader下载线程。WtptpDownloader.c:989-1010 +BootRom和BootLoader下载过程类似,都是通过调用WtptpDownLoad_WTPTPDownLoad函数来进行下载。主要区别是BootLoader下载完成后,会将下载状态设置为kProcCompleted(成功WtptpDownloader.c:251)或kProcAborting(失败WtptpDownloader.c:258),此后工具会退出;BootRom下载完成后工具不会退出,设备检测线程会继续运行。 + +下面将描述下载的核心函数的流程WtptpDownloader.c:2044 BOOL WtptpDownLoad_WTPTPDownLoad(struct CWtptpDownLoad *me,PDEVICE pDev) +WtptpDownloader.c:2049-2141 设置下载相关参数和下载的Image List,计算下载总大小。 +WtptpDownloader.c:2143-2561 对每个image进行下载和烧写 + WtptpDownloader.c:2153 WtptpDownLoad_DownloadImage + WtptpDownloader.c:1019 BOOL WtptpDownLoad_DownloadImage(struct CWtptpDownLoad *me,PDEVICE pdev, int iFile,const t_ImageFileList* plImgFileList, UINT64 uiAllimgsize,UINT64 *uidownloadsize,int nImages,char* strDownloadImgName) + 该函数将image下载至模块DDR中,大致流程为: + 1、SendPreamble + 2、GetVersion + 以上两步在下载第一个image时省略,因为WtptpDownLoad_GetDeviceBootType中已经执行上两个步骤 + 3、SelectImage WtptpDownloader.c:1103 + 4、VerifyImage WtptpDownloader.c:1117 + 5、GetBadBlockInfo WtptpDownloader.c:1188 + 6、DataHeader + 7、Data(将image所有数据通过Data传输完) + 8、Done WtptpDownloader.c:1447 + WtptpDownloader.c:2160-2552 Image下载到DDR后,模块开始将image烧写到flash,该段代码主要通过GetWtpMessage获取模块烧写过程中的状态: + WtptpDownloader.c:2512 当工具收到模块处于PlatformReady状态消息后,表明image烧写完毕。 + +所有image下载烧写完毕后,如果在blf中使能CRC校验(部分平台支持),模块会计算烧写完的image CRC,并上报给工具。WtptpDownloader.c:2565-2596 + +其他说明:上述下载过程中提及的image并非指BinFile.bin文件。BinFile.bin是包括下载参数、下载image等内容的包文件,下载过程中通过BinFileWtp.h中的类(c++移植到c形式的类)来解析。 diff --git a/hotplug-generator/Makefile b/hotplug-generator/Makefile new file mode 100755 index 00000000..fb4b25b3 --- /dev/null +++ b/hotplug-generator/Makefile @@ -0,0 +1,38 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=hotplug-generator +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/hotplug-generator + +include $(INCLUDE_DIR)/package.mk + +define Package/hotplug-generator + TITLE:=generator of hotplug scripts + SECTION:=utils + CATEGORY:=Utilities + PKGARCH:=all +endef + +define Package/hotplug-generator/description + This package contains additional scripts and configuration files for generation hotplug scripts +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/hotplug-generator/install + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/hotplug.config $(1)/etc/config/hotplug + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/hotplug.init $(1)/etc/init.d/hotplug +endef + +$(eval $(call BuildPackage,hotplug-generator)) diff --git a/hotplug-generator/files/hotplug.config b/hotplug-generator/files/hotplug.config new file mode 100755 index 00000000..2a250937 --- /dev/null +++ b/hotplug-generator/files/hotplug.config @@ -0,0 +1,8 @@ +config iface 'gre' + option action 'ifup' + option enabled '0' + list command 'sleep 5' + list command 'ip route add 10.10.1.1 dev $DEVICE' + list command 'ip route add 192.168.13.1 dev $DEVICE' + option description 'GRE: +routes via $DEVICE after 5s' + option interface 'gre_tun2' diff --git a/hotplug-generator/files/hotplug.init b/hotplug-generator/files/hotplug.init new file mode 100755 index 00000000..f6b6a267 --- /dev/null +++ b/hotplug-generator/files/hotplug.init @@ -0,0 +1,50 @@ +#!/bin/sh /etc/rc.common + +START=10 +USE_PROCD=1 +IFACE_PATH="/etc/hotplug.d/iface/90-hp-generator" + +add_iface_rule() { + local enabled action command description interface + + config_get enabled "$1" enabled + [ "$enabled" = "0" ] && continue + + config_get action "$1" action + config_get description "$1" description + config_get interface "$1" interface + + echo "#!/bin/sh" >> "$IFACE_PATH-$1" + echo "# Generated automatically, to change it use /etc/config/hotplug" >> "$IFACE_PATH-$1" + description=$(echo $description | tr '\n' ' ') + echo "# Description: $description" >> "$IFACE_PATH-$1" + echo "" >> "$IFACE_PATH-$1" + + echo "if [ \"\$ACTION\" = \"$action\" ]; then" >> "$IFACE_PATH-$1" + echo " if [ \"\$INTERFACE\" = \"$interface\" ]; then" >> "$IFACE_PATH-$1" + + command_list=$(uci -q get hotplug."$1".command) + [ "${command_list:0:1}" = "'" ] && command_list=$(echo ${command_list:1}) + [ "${command_list: -1}" = "'" ] && command_list=$(echo ${command_list:0:-1}) + i=0 + while true ; do + i=$((i+1)) + command=$(echo $command_list | awk -v i=$i -F "' '" '{print $i}') + [ -z "$command" ] && break + echo " $command" >> "$IFACE_PATH-$1" + done + + echo " fi" >> "$IFACE_PATH-$1" + echo "fi" >> "$IFACE_PATH-$1" + echo "exit 0" >> "$IFACE_PATH-$1" +} + +start_service() { + rm "$IFACE_PATH-"* 2>/dev/null + config_load hotplug + config_foreach add_iface_rule iface +} + +service_triggers() { + procd_add_reload_trigger "hotplug" +} diff --git a/iolines/Makefile b/iolines/Makefile new file mode 100755 index 00000000..68a4f122 --- /dev/null +++ b/iolines/Makefile @@ -0,0 +1,38 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=iolines +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/iolines + +include $(INCLUDE_DIR)/package.mk + +define Package/iolines + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Network interface watchdog + DEPENDS:= +endef + +define Package/iolines/description + This package contains a utility for managing the interface using ping requests. +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/iolines/install + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/iolines.config $(1)/etc/config/iolines + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/iolines.init $(1)/etc/init.d/iolines +endef + +$(eval $(call BuildPackage,iolines)) diff --git a/iolines/files/iolines.config b/iolines/files/iolines.config new file mode 100644 index 00000000..17ed36cc --- /dev/null +++ b/iolines/files/iolines.config @@ -0,0 +1,23 @@ +config io + option name "IO1" + option dev "adc0" + option enabled "0" + option mode "mode1" + +config io + option name "IO2" + option dev "adc1" + option enabled "0" + option mode "mode1" + +config io + option name "IO3" + option dev "adc2" + option enabled "0" + option mode "mode1" + +config io + option name "IO4" + option dev "adc3" + option enabled "0" + option mode "mode1" diff --git a/iolines/files/iolines.init b/iolines/files/iolines.init new file mode 100755 index 00000000..821600c6 --- /dev/null +++ b/iolines/files/iolines.init @@ -0,0 +1,112 @@ +#!/bin/sh /etc/rc.common + +START=50 + +load_iolines_boot() { + + config_get dev "$1" "dev" + + num=$(echo ${dev:3:1}) + pu="/dev/pu$num" + pd="/dev/pd$num" + + config_get mode "$1" "mode" + config_get enabled "$1" "enabled" "0" + if [ $enabled -eq 1 ]; then + case "$mode" in + "mode1") + echo in > $pu/direction + echo low > $pd/direction + ;; + "mode2") + echo low > $pu/direction + echo low > $pd/direction + ;; + "mode3") + echo high > $pu/direction + echo high > $pd/direction + ;; + esac + else + echo in > $pu/direction + echo low > $pd/direction + fi +} + +load_iolines() { + + config_get dev "$1" "dev" + + num=$(echo ${dev:3:1}) + pu="/dev/pu$num" + pd="/dev/pd$num" + + config_get mode "$1" "mode" + + case "$mode" in + "mode1") + echo in > $pu/direction + echo low > $pd/direction + ;; + "mode2") + echo low > $pu/direction + echo low > $pd/direction + ;; + "mode3") + echo high > $pu/direction + echo high > $pd/direction + ;; + esac + +} + +boot() { + echo 51 > /sys/class/gpio/export + echo 50 > /sys/class/gpio/export + echo 54 > /sys/class/gpio/export + echo 53 > /sys/class/gpio/export + echo 57 > /sys/class/gpio/export + echo 64 > /sys/class/gpio/export + echo 66 > /sys/class/gpio/export + echo 65 > /sys/class/gpio/export + + ln -s /sys/bus/iio/devices/iio\:device0/in_voltage3_raw /dev/board + BOARD=$((($(cat /dev/board)+$(cat /dev/board)+$(cat /dev/board))/3)) + + if [ "$BOARD" -gt "600" -a "$BOARD" -lt "900" ]; then + echo v4 > /tmp/sysinfo/hw + ln -s /sys/class/gpio/gpio51 /dev/pu3 + ln -s /sys/class/gpio/gpio50 /dev/pd3 + ln -s /sys/class/gpio/gpio54 /dev/pu2 + ln -s /sys/class/gpio/gpio53 /dev/pd2 + ln -s /sys/class/gpio/gpio57 /dev/pu1 + ln -s /sys/class/gpio/gpio64 /dev/pd1 + ln -s /sys/class/gpio/gpio66 /dev/pu0 + ln -s /sys/class/gpio/gpio65 /dev/pd0 + ln -s /sys/bus/iio/devices/iio\:device0/in_voltage0_raw /dev/io3 + ln -s /sys/bus/iio/devices/iio\:device0/in_voltage1_raw /dev/io2 + ln -s /sys/bus/iio/devices/iio\:device0/in_voltage4_raw /dev/io1 + ln -s /sys/bus/iio/devices/iio\:device0/in_voltage6_raw /dev/io0 + else + echo v2 > /tmp/sysinfo/hw + ln -s /sys/class/gpio/gpio51 /dev/pu0 + ln -s /sys/class/gpio/gpio50 /dev/pd0 + ln -s /sys/class/gpio/gpio54 /dev/pu1 + ln -s /sys/class/gpio/gpio53 /dev/pd1 + ln -s /sys/class/gpio/gpio57 /dev/pu2 + ln -s /sys/class/gpio/gpio64 /dev/pd2 + ln -s /sys/class/gpio/gpio66 /dev/pu3 + ln -s /sys/class/gpio/gpio65 /dev/pd3 + ln -s /sys/bus/iio/devices/iio\:device0/in_voltage0_raw /dev/io0 + ln -s /sys/bus/iio/devices/iio\:device0/in_voltage1_raw /dev/io1 + ln -s /sys/bus/iio/devices/iio\:device0/in_voltage4_raw /dev/io2 + ln -s /sys/bus/iio/devices/iio\:device0/in_voltage6_raw /dev/io3 + fi + config_load iolines + config_foreach load_iolines_boot io +} + +restart() { + config_load iolines + config_foreach load_iolines io +} diff --git a/linux-serial-test/Makefile b/linux-serial-test/Makefile new file mode 100644 index 00000000..1378eaa3 --- /dev/null +++ b/linux-serial-test/Makefile @@ -0,0 +1,34 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=linux-serial-test +PKG_VERSION:=1 +PKG_RELEASE:=1 + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL=https://github.com/cbrake/linux-serial-test.git +PKG_SOURCE_DATE:=2024-01-15 +PKG_SOURCE_VERSION:=6a28493a29f7b941172bc58cf4fdabbf8109022f +PKG_MIRROR_HASH:=skip + +include $(INCLUDE_DIR)/package.mk + +define Package/linux-serial-test + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Linux Serial Test Application +endef + +define Package/linux-serial-test/description + Linux Serial Test Application +endef + +define Build/Compile + $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) $(PKG_BUILD_DIR)/linux-serial-test.c -o $(PKG_BUILD_DIR)/linux-serial-test +endef + +define Package/linux-serial-test/install + $(INSTALL_DIR) $(1)/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/linux-serial-test $(1)/bin/ +endef + +$(eval $(call BuildPackage,linux-serial-test)) diff --git a/luci-app-hotplug/Makefile b/luci-app-hotplug/Makefile index 6c03756b..1a45f17b 100644 --- a/luci-app-hotplug/Makefile +++ b/luci-app-hotplug/Makefile @@ -6,7 +6,7 @@ LUCI_TITLE:=LuCI interface for hotplug configuration LUCI_DEPENDS:=+luci-base LUCI_PKGARCH:=all PKG_VERSION:=1.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/luci-app-hotplug/root/etc/uci-defaults/hotplug b/luci-app-hotplug/root/etc/uci-defaults/hotplug deleted file mode 100644 index dd1ef089..00000000 --- a/luci-app-hotplug/root/etc/uci-defaults/hotplug +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -[ ! -f "/usr/share/ucitrack/luci-app-hotplug.json" ] && { - cat > /usr/share/ucitrack/luci-app-hotplug.json << EEOF -{ - "config": "hotplug", - "init": "hotplug" -} -EEOF -} - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@hotplug[-1] - add ucitrack hotplug - set ucitrack.@hotplug[-1].init=hotplug - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 diff --git a/luci-app-pollmydevice/Makefile b/luci-app-pollmydevice/Makefile index dd94f0d2..d7885530 100755 --- a/luci-app-pollmydevice/Makefile +++ b/luci-app-pollmydevice/Makefile @@ -5,7 +5,7 @@ LUCI_DEPENDS:= +pollmydevice PKG_VERSION:=1.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI TCP to RS232 and RS485 Configuration Frontend diff --git a/luci-app-pollmydevice/htdocs/luci-static/resources/view/pollmydevice/pollmydevice.js b/luci-app-pollmydevice/htdocs/luci-static/resources/view/pollmydevice/pollmydevice.js index 2324e147..aa05ec12 100644 --- a/luci-app-pollmydevice/htdocs/luci-static/resources/view/pollmydevice/pollmydevice.js +++ b/luci-app-pollmydevice/htdocs/luci-static/resources/view/pollmydevice/pollmydevice.js @@ -61,8 +61,8 @@ return view.extend({ uci.set('pollmydevice', section_id, 'baudrate','9600'); uci.set('pollmydevice', section_id, 'bytesize','8'); uci.set('pollmydevice', section_id, 'mode','disabled'); - uci.set('pollmydevice', section_id, 'open_in_firewall','1') - uci.set('pollmydevice', section_id, 'server_port',String(30000+i)) + uci.set('pollmydevice', section_id, 'open_in_firewall','1'); + uci.set('pollmydevice', section_id, 'server_port',String(30000+i)); this.addedSection = section_id; return this.renderMoreOptionsModal(section_id); }; @@ -130,7 +130,7 @@ return view.extend({ o.modalonly = true; o.default = 0; o.datatype = 'and(uinteger, min(0), max(255))'; - for(i=1;i<256;i++){ + for (var i = 1; i < 256; i++){ o.depends({pack_size: i.toString()}); } diff --git a/luci-app-powersupply/root/etc/uci-defaults/powersupply b/luci-app-powersupply/root/etc/uci-defaults/powersupply deleted file mode 100644 index e1a4245c..00000000 --- a/luci-app-powersupply/root/etc/uci-defaults/powersupply +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -[ ! -f "/usr/share/ucitrack/luci-app-powersupply.json" ] && { - cat > /usr/share/ucitrack/luci-app-powersupply.json << EEOF -{ - "config": "powersupply", - "init": "powersupply" -} -EEOF -} - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@powersupply[-1] - add ucitrack powersupply - set ucitrack.@powersupply[-1].init=powersupply - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 diff --git a/luci-app-pptpd/root/etc/uci-defaults/pptpd b/luci-app-pptpd/root/etc/uci-defaults/pptpd deleted file mode 100644 index 66e4d58d..00000000 --- a/luci-app-pptpd/root/etc/uci-defaults/pptpd +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -[ ! -f "/usr/share/ucitrack/luci-app-pptpd.json" ] && { - cat > /usr/share/ucitrack/luci-app-pptpd.json << EEOF -{ - "config": "pptpd", - "init": "pptpd" -} -EEOF -} - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@pptpd[-1] - add ucitrack pptpd - set ucitrack.@pptpd[-1].init=pptpd - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 diff --git a/luci-app-simman/Makefile b/luci-app-simman/Makefile index 977b787c..228689c3 100755 --- a/luci-app-simman/Makefile +++ b/luci-app-simman/Makefile @@ -10,7 +10,7 @@ LUCI_DEPENDS:=+simman # Version: .. PKG_VERSION:=0.2.6 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_MAINTAINER:=Sklyarec Konstantin Vladimir Ovseychuk diff --git a/luci-app-simman/root/etc/uci-defaults/simman b/luci-app-simman/root/etc/uci-defaults/simman deleted file mode 100644 index 9f3a8074..00000000 --- a/luci-app-simman/root/etc/uci-defaults/simman +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -[ ! -f "/usr/share/ucitrack/luci-app-simman.json" ] && { - cat > /usr/share/ucitrack/luci-app-simman.json << EEOF -{ - "config": "simman", - "init": "simman" -} -EEOF -} - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@simman[-1] - add ucitrack simman - set ucitrack.@simman[-1].init=simman - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 diff --git a/luci-app-smscontrol/Makefile b/luci-app-smscontrol/Makefile index cf5fc84e..ae44b4c8 100755 --- a/luci-app-smscontrol/Makefile +++ b/luci-app-smscontrol/Makefile @@ -10,7 +10,7 @@ LUCI_DEPENDS:= # Version: .. PKG_VERSION:=0.2.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 LUCI_TITLE:=LuCI utility to remote control via SMS diff --git a/luci-app-smscontrol/root/etc/uci-defaults/smscontrol b/luci-app-smscontrol/root/etc/uci-defaults/smscontrol deleted file mode 100644 index 7ddcf87c..00000000 --- a/luci-app-smscontrol/root/etc/uci-defaults/smscontrol +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -[ ! -f "/usr/share/ucitrack/luci-app-smscontrol.json" ] && { - cat > /usr/share/ucitrack/luci-app-smscontrol.json << EEOF -{ - "config": "smscontrol", - "init": "smscontrol" -} -EEOF -} - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@smscontrol[-1] - add ucitrack smscontrol - set ucitrack.@smscontrol[-1].init=smscontrol - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 diff --git a/luci-app-snmpd-ssl/root/etc/uci-defaults/snmpd-ssl b/luci-app-snmpd-ssl/root/etc/uci-defaults/snmpd-ssl deleted file mode 100644 index 7704bb22..00000000 --- a/luci-app-snmpd-ssl/root/etc/uci-defaults/snmpd-ssl +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -[ ! -f "/usr/share/ucitrack/luci-app-snmpd.json" ] && { - cat > /usr/share/ucitrack/luci-app-snmpd.json << EEOF -{ - "config": "snmpd", - "init": "snmpd" -} -EEOF -} - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@snmpd[-1] - add ucitrack snmpd - set ucitrack.@snmpd[-1].init=snmpd - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 diff --git a/luci-app-strongswan/root/usr/share/luci/menu.d/luci-app-strongswan.json b/luci-app-strongswan/root/usr/share/luci/menu.d/luci-app-strongswan.json index cb96b8df..726a59a6 100644 --- a/luci-app-strongswan/root/usr/share/luci/menu.d/luci-app-strongswan.json +++ b/luci-app-strongswan/root/usr/share/luci/menu.d/luci-app-strongswan.json @@ -1,7 +1,6 @@ { "admin/vpn/strongswan": { "title": "IPsec", - "order": 85, "action": { "type": "view", "path": "strongswan/strongswan" diff --git a/luci-app-xl2tpd/root/etc/uci-defaults/xl2tpd b/luci-app-xl2tpd/root/etc/uci-defaults/xl2tpd deleted file mode 100644 index d985337a..00000000 --- a/luci-app-xl2tpd/root/etc/uci-defaults/xl2tpd +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -[ ! -f "/usr/share/ucitrack/luci-app-xl2tpd.json" ] && { - cat > /usr/share/ucitrack/luci-app-xl2tpd.json << EEOF -{ - "config": "xl2tpd", - "init": "xl2tpd" -} -EEOF -} - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@xl2tpd[-1] - add ucitrack xl2tpd - set ucitrack.@xl2tpd[-1].init=xl2tpd - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 diff --git a/luci-app-zabbix/Makefile b/luci-app-zabbix/Makefile index ee06c282..25dd07d6 100644 --- a/luci-app-zabbix/Makefile +++ b/luci-app-zabbix/Makefile @@ -4,7 +4,7 @@ PKG_NAME:=luci-app-zabbix LUCI_TITLE:=zabbix agentd configuration LUCI_DEPENDS:=+luci-base -LUCI_DEPENDS:=zabbix-agentd-ssl +LUCI_DEPENDS:=zabbix-agentd-openssl LUCI_PKGARCH:=all include $(TOPDIR)/feeds/luci/luci.mk diff --git a/luci-app-zabbix/root/etc/uci-defaults/zabbix b/luci-app-zabbix/root/etc/uci-defaults/zabbix deleted file mode 100644 index ef4c3937..00000000 --- a/luci-app-zabbix/root/etc/uci-defaults/zabbix +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -[ ! -f "/usr/share/ucitrack/luci-app-zabbix.json" ] && { - cat > /usr/share/ucitrack/luci-app-zabbix.json << EEOF -{ - "config": "zabbix", - "init": "zabbix" -} -EEOF -} - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@zabbix[-1] - add ucitrack zabbix - set ucitrack.@zabbix[-1].init=zabbix_agentd - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 diff --git a/luci-theme-teleofis/luasrc/view/themes/teleofis/footer.htm b/luci-theme-teleofis/luasrc/view/themes/teleofis/footer.htm index d15dfa36..dbef3ac8 100644 --- a/luci-theme-teleofis/luasrc/view/themes/teleofis/footer.htm +++ b/luci-theme-teleofis/luasrc/view/themes/teleofis/footer.htm @@ -8,7 +8,7 @@ <% local ver = require "luci.version" %>
-
© TELEOFIS 2004-2026 
+
© TELEOFIS 2004-2025 
diff --git a/mxsldr/Makefile b/mxsldr/Makefile new file mode 100644 index 00000000..814106e8 --- /dev/null +++ b/mxsldr/Makefile @@ -0,0 +1,41 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=mxsldr +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/mxsldr + +include $(INCLUDE_DIR)/package.mk + +define Package/mxsldr + SECTION:=utils + CATEGORY:=Utilities + TITLE:= The i.MX233/i.MX28 USB Loader + DEPENDS:=+libusb-1.0 +endef + +define Package/mxsldr/description + This tool allows user to load U-Boot via BootROM USB download. +endef + +TARGET_CFLAGS += \ + -I$(STAGING_DIR)/usr/include/libusb-1.0 + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + CC="$(TARGET_CC)" \ + CFLAGS="$(TARGET_CFLAGS) -Wall" +endef + +define Package/mxsldr/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/mxsldr $(1)/usr/bin +endef + +$(eval $(call BuildPackage,mxsldr)) diff --git a/mxsldr/src/COPYING b/mxsldr/src/COPYING new file mode 100644 index 00000000..d159169d --- /dev/null +++ b/mxsldr/src/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/mxsldr/src/Makefile b/mxsldr/src/Makefile new file mode 100644 index 00000000..95cd33af --- /dev/null +++ b/mxsldr/src/Makefile @@ -0,0 +1,24 @@ +DESTDIR ?= +prefix ?= "/usr/local" +PKG_CONFIG ?= pkg-config + +LIBUSB_FOUND := $(shell $(PKG_CONFIG) --atleast-version=1 libusb-1.0 && echo Y) + +ifneq ($(LIBUSB_FOUND),Y) +$(error Missing libusb!) +endif + +CFLAGS += $(shell $(PKG_CONFIG) --cflags libusb-1.0) +LIBS += $(shell $(PKG_CONFIG) --libs libusb-1.0) + +all: mxsldr + +mxsldr: mxsldr.c + $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ -lusb-1.0 + +install: mxsldr + mkdir -p $(DESTDIR)/$(prefix)/bin + install -m 755 $^ $(DESTDIR)/$(prefix)/bin + +clean: + rm -f mxsldr diff --git a/mxsldr/src/README b/mxsldr/src/README new file mode 100644 index 00000000..1ea971d2 --- /dev/null +++ b/mxsldr/src/README @@ -0,0 +1,31 @@ +Freescale i.MX233/i.MX28 USB loader +=================================== + +This tool allows user to load U-Boot via BootROM USB download. + +Prerequisites: +============== + +This tool depends on libusb 1.0, make sure to install development +version of this library. + + +In case your kernel is very outdated, meaning kernel older than 3.7.4, +3.4.26 (stable) etc. or if your kernel does not properly handle the +MXS BootROM recovery mode, which can be seen in 'dmesg' output by +kernel reporting that the device is ignored due to problem with HID +descriptor, apply patches (*.diff) onto kernel on your host machine +and rebuild the kernel. Then restart the machine with the new kernel. + +Usage: +====== + +1) Connect the MX233/MX28 device to USB via device cable + +2) Compile U-Boot and produce u-boot.sb + +3) Compile this tool: + $ make + +4) Load u-boot.sb onto the device: + $ sudo ./mxsldr diff --git a/mxsldr/src/hid1.diff b/mxsldr/src/hid1.diff new file mode 100644 index 00000000..959bd873 --- /dev/null +++ b/mxsldr/src/hid1.diff @@ -0,0 +1,11 @@ +--- a/drivers/hid/hid-core.c 2012-08-04 23:53:38.900126160 +0200 ++++ b/drivers/hid/hid-core.c 2012-08-04 23:54:03.148127188 +0200 +@@ -374,7 +374,7 @@ + + case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: + parser->global.report_size = item_udata(item); +- if (parser->global.report_size > 96) { ++ if (parser->global.report_size > 128) { + hid_err(parser->device, "invalid report_size %d\n", + parser->global.report_size); + return -1; diff --git a/mxsldr/src/hid2.diff b/mxsldr/src/hid2.diff new file mode 100644 index 00000000..ac6a5b9e --- /dev/null +++ b/mxsldr/src/hid2.diff @@ -0,0 +1,26 @@ +--- a/drivers/hid/usbhid/hid-quirks.c 2012-08-05 02:58:15.880274023 +0200 ++++ b/drivers/hid/usbhid/hid-quirks.c 2012-08-05 02:58:10.228273782 +0200 +@@ -102,6 +102,8 @@ + { USB_VENDOR_ID_SIGMA_MICRO, USB_DEVICE_ID_SIGMA_MICRO_KEYBOARD, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M610X, HID_QUIRK_MULTI_INPUT }, ++ { USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET }, ++ { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, + { 0, 0 } + }; + +--- a/drivers/hid/hid-ids.h 2012-08-05 02:59:00.340275908 +0200 ++++ b/drivers/hid/hid-ids.h 2012-08-05 02:58:56.008275723 +0200 +@@ -296,6 +296,12 @@ + #define USB_VENDOR_ID_EZKEY 0x0518 + #define USB_DEVICE_ID_BTC_8193 0x0002 + ++#define USB_VENDOR_ID_FREESCALE 0x15A2 ++#define USB_DEVICE_ID_FREESCALE_MX28 0x004F ++ ++#define USB_VENDOR_ID_SIGMATEL 0x066F ++#define USB_DEVICE_ID_SIGMATEL_STMP3780 0x3780 ++ + #define USB_VENDOR_ID_FRUCTEL 0x25B6 + #define USB_DEVICE_ID_GAMETEL_MT_MODE 0x0002 + diff --git a/mxsldr/src/mxsldr.c b/mxsldr/src/mxsldr.c new file mode 100644 index 00000000..1de5f49b --- /dev/null +++ b/mxsldr/src/mxsldr.c @@ -0,0 +1,294 @@ +/* + * Freescale i.MX233/i.MX28 USB loader + * + * Copyright (C) 2012 Marek Vasut + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +#include + +#define TRANSFER_TIMEOUT_MS 60000 +#define HID_SET_REPORT 0x09 +#define HID_REPORT_TYPE_OUTPUT 0x02 + +#define MX23_VID 0x066f +#define MX23_PID 0x3780 +#define MX28_VID 0x15a2 +#define MX28_PID 0x004f + +#define BLTC_CMD_INQUIRY 0x01 +#define BLTC_CMD_DOWNLOAD_FIRMWARE 0x02 + +#define BLTC_PAGE_INQUIRY_CHIP_INFO 0x01 + +struct page_inquiry_chip_info { + uint16_t chip_id; + uint8_t __pad; + uint8_t chip_rev; + uint16_t rom_ver; + uint16_t proto_ver; +}; + +static int get_mxs_dev(libusb_device_handle **h) +{ + int i, cnt, ret; + struct libusb_device_descriptor desc; + libusb_device **devs; + libusb_device *rdev = NULL; + + cnt = libusb_get_device_list(NULL, &devs); + if (cnt < 0) + return -EINVAL; + + for (i = 0; i < cnt; i++) { + if (!devs[i]) + continue; + + ret = libusb_get_device_descriptor(devs[i], &desc); + if (ret < 0) + continue; + + if (desc.idVendor == MX23_VID && desc.idProduct == MX23_PID) { + rdev = devs[i]; + break; + } + + if (desc.idVendor == MX28_VID && desc.idProduct == MX28_PID) { + rdev = devs[i]; + break; + } + } + + if (!rdev) { + fprintf(stderr, "No compatible device found.\n"); + ret = -ENODEV; + goto exit; + } + + ret = libusb_open(rdev, h); + if (ret) + fprintf(stderr, "Could not open device, ret=%i\n", ret); +exit: + libusb_free_device_list(devs, 1); + return ret; +} + +static int transfer(struct libusb_device_handle *h, int report, + unsigned char *buf, unsigned cnt, int *offset) +{ + int ret; + int last_trans = 0; + const int control_transfer = + LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_CLASS | + LIBUSB_RECIPIENT_INTERFACE; + const int interrupt_transfer = + LIBUSB_RECIPIENT_INTERFACE | LIBUSB_ENDPOINT_IN; + + if (report < 3) { + ret = libusb_control_transfer(h, control_transfer, + HID_SET_REPORT, + (HID_REPORT_TYPE_OUTPUT << 8) | report, + 0, buf, cnt, TRANSFER_TIMEOUT_MS); + last_trans = (ret > 0) ? ret - 1 : 0; + if (ret > 0) + ret = 0; + } else { + if (cnt > 64) + cnt = 64; + ret = libusb_interrupt_transfer(h, interrupt_transfer, + buf, cnt, &last_trans, + TRANSFER_TIMEOUT_MS); + } + + *offset += last_trans; + + return ret; +} + +static int detect_mxs_cpu(libusb_device_handle *h) +{ + int ret; + uint8_t buf[1025]; + uint8_t fin[14]; + int last_trans = 0; + const int len = sizeof(buf); + struct page_inquiry_chip_info *info; + info = (struct page_inquiry_chip_info *)(buf + 1); + + const uint8_t inquiry_chip_info[] = { + BLTC_CMD_INQUIRY, 'B', 'L', 'T', 'C', 0, 0, 0, + 0, 0x04, 0, 0, + 0, 0x80, 0, 0, + + BLTC_CMD_INQUIRY, BLTC_PAGE_INQUIRY_CHIP_INFO, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }; + + ret = transfer(h, 1, (uint8_t *)inquiry_chip_info, + sizeof(inquiry_chip_info), &last_trans); + if (ret) + return ret; + + memset(buf, 0, sizeof(buf)); + + last_trans = 0; + do { + ret = transfer(h, 3, buf + last_trans, len, &last_trans); + if (ret) + return ret; + } while (last_trans < len); + + last_trans = 0; + ret = transfer(h, 4, fin, sizeof(fin), &last_trans); + if (ret) + return ret; + + if ((fin[0] != 0x04) || memcmp(fin + 1, "BLTS", 4)) + return -EINVAL; + + printf("Detected: i.MX%i\n" + "Chip ID: 0x%04x\n" + "Chip Revision: 0x%04x\n" + "ROM Version: 0x%04x\n" + "Protocol Version: 0x%04x\n", + (info->chip_id == 0x2800) ? 28 : 23, + info->chip_id, info->chip_rev, + info->rom_ver, info->proto_ver); + + return 0; +} + + + +static int upload_firmware(char *fn, libusb_device_handle *h) +{ + FILE *f; + long len, tmplen; + uint8_t buf[1025] = { BLTC_CMD_DOWNLOAD_FIRMWARE }; + int ret = 0; + int last_trans = 0; + + uint8_t inquiry_download_fw[] = { + BLTC_CMD_INQUIRY, 'B', 'L', 'T', 'C', 1, 0, 0, + 0, 0x60, 0x24, 0x4a, + 0, 0, 0, 0, + + BLTC_CMD_DOWNLOAD_FIRMWARE, 0, 0x4a, 0x24, + 0x60, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + }; + + f = fopen(fn, "rb"); + if (!f) { + fprintf(stderr, "Failed to open firmware (%s)\n", fn); + return -EINVAL; + } + + ret = fseek(f, 0, SEEK_END); + if (ret) + goto exit; + + len = ftell(f); + if (len <= 0) + goto exit; + tmplen = __builtin_bswap32(len); + + memcpy(inquiry_download_fw + 9, &len, 4); + memcpy(inquiry_download_fw + 17, &tmplen, 4); + + ret = fseek(f, 0, SEEK_SET); + if (ret) + goto exit; + + ret = transfer(h, 1, (uint8_t *)inquiry_download_fw, + sizeof(inquiry_download_fw), &last_trans); + if (ret) { + fprintf(stderr, + "An Error occured while transfering the firmware through USB.\n"); + goto exit; + } + + while ((len = fread(buf + 1, 1, sizeof(buf) - 1, f))) { + buf[0] = BLTC_CMD_DOWNLOAD_FIRMWARE; + ret = transfer(h, 2, buf, len + 1, &last_trans); + if (ret) + goto exit; + } + +exit: + fclose(f); + return ret; +} + +void print_usage() +{ + printf( + "Usage: mxsldr \n" + " (e.g: u-boot.sb)\n"); +} + +int main(int argc, char const *const argv[]) +{ + int ret; + libusb_device_handle *h = NULL; + + /* Detect and exit. */ + if (argc != 2) { + print_usage(); + return 1; + } + + ret = libusb_init(NULL); + if (ret < 0) + goto out; + + ret = get_mxs_dev(&h); + if (ret) + goto out; + if (!h) + goto out; + + if (libusb_kernel_driver_active(h, 0)) + libusb_detach_kernel_driver(h, 0); + + ret = libusb_claim_interface(h, 0); + if (ret) { + fprintf(stderr, "Failed to claim interface\n"); + goto out; + } + + ret = detect_mxs_cpu(h); + if (ret) { + fprintf(stderr, "Failed to detect CPU\n"); + goto exit; + } + + ret = upload_firmware((char *)argv[1], h); + if (ret) + goto exit; + +exit: + libusb_release_interface(h, 0); +out: + if (h) + libusb_close(h); + + libusb_exit(NULL); + return ret; +} diff --git a/net-snmp-ssl/Config.in.wut b/net-snmp-ssl/Config.in.wut new file mode 100644 index 00000000..2b5e9fb2 --- /dev/null +++ b/net-snmp-ssl/Config.in.wut @@ -0,0 +1,14 @@ +menu "Configuration" + depends on PACKAGE_libnetsnmp + +config SNMP_WITH_PERL_EMBEDDED + bool + default n + prompt "Enable embedded perl in the SNMP agent and snmptrapd." + +config SNMP_WITH_PERL_MODULES + bool + default n + prompt "Install perl modules" + +endmenu diff --git a/net-snmp-ssl/Makefile b/net-snmp-ssl/Makefile new file mode 100644 index 00000000..977b8733 --- /dev/null +++ b/net-snmp-ssl/Makefile @@ -0,0 +1,287 @@ +# +# Copyright (C) 2006-2017 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=net-snmp +PKG_VERSION:=5.9.4 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@SF/net-snmp +PKG_HASH:=skip +PKG_MAINTAINER:=Stijn Tintel +PKG_LICENSE:=MIT BSD-3-Clause-Clear +PKG_CPE_ID:=cpe:/a:net-snmp:net-snmp + +PKG_FIXUP:=autoreconf + +include $(INCLUDE_DIR)/package.mk + +define Package/net-snmp-ssl/Default + SECTION:=net + CATEGORY:=Network + URL:=http://www.net-snmp.org/ +endef + +define Package/net-snmp-ssl/Default/description + Simple Network Management Protocol (SNMP) is a widely used protocol for + monitoring the health and welfare of network equipment (eg. routers), + computer equipment and even devices like UPSs. Net-SNMP is a suite of + applications used to implement SNMP v1, SNMP v2c and SNMP v3 using both + IPv4 and IPv6. +endef + + +define Package/libnetsnmp-ssl +$(call Package/net-snmp-ssl/Default) + SECTION:=libs + CATEGORY:=Libraries + DEPENDS:=+libnl-tiny +libpci +libpcre2 +libopenssl + TITLE:=Open source SNMP implementation (libraries) +endef + +define Package/libnetsnmp-ssl/description +$(call Package/net-snmp-ssl/Default/description) + . + This package contains shared libraries, needed by other programs. +endef + + +define Package/snmp-mibs-ssl +$(call Package/net-snmp-ssl/Default) + TITLE:=Open source SNMP implementation (MIB-files) +endef + +define Package/snmp-mibs-ssl/description +$(call Package/net-snmp-ssl/Default/description) + . + This package contains SNMP MIB-Files. +endef + + +define Package/snmp-utils-ssl +$(call Package/net-snmp-ssl/Default) + DEPENDS:=+libnetsnmp-ssl + TITLE:=Open source SNMP implementation (utilities) +endef + +define Package/snmp-utils-ssl/description +$(call Package/net-snmp-ssl/Default/description) + . + This package contains SNMP client utilities: + - snmpget + - snmpset + - snmpstatus + - snmptest + - snmptrap + - snmpwalk +endef + + +define Package/snmpd-ssl +$(call Package/net-snmp-ssl/Default) + DEPENDS:=+libnetsnmp-ssl + TITLE:=Open source SNMP implementation (daemon) +endef + +define Package/snmpd-ssl/description +$(call Package/net-snmp-ssl/Default/description) + . + This package contains the SNMP agent, dynamically linked. +endef + + +define Package/snmpd-static-ssl +$(call Package/net-snmp-ssl/Default) + DEPENDS:=+snmpd-ssl + TITLE:=Open source SNMP implementation (daemon) + BUILDONLY:=1 +endef + + +define Package/snmptrapd-ssl +$(call Package/net-snmp-ssl/Default) + DEPENDS:=+libnetsnmp-ssl + TITLE:=Open source SNMP implementation (notification receiver) +endef + +define Package/snmptrapd-ssl/description +$(call Package/net-snmp-ssl/Default/description) + . + This package contains the SNMP notification receiver. +endef + + +SNMP_MIB_MODULES_INCLUDED = \ + agent/extend \ + agentx \ + host/hr_device \ + host/hr_disk \ + host/hr_filesys \ + host/hr_network \ + host/hr_partition \ + host/hr_proc \ + host/hr_storage \ + host/hr_system \ + ieee802dot11 \ + if-mib/ifXTable \ + ip-mib/ipAddressTable \ + ip-mib/inetNetToMediaTable \ + ip-forward-mib/inetCidrRouteTable \ + ip-forward-mib/ipCidrRouteTable \ + mibII/at \ + mibII/icmp \ + mibII/ifTable \ + mibII/ip \ + mibII/snmp_mib \ + mibII/sysORTable \ + mibII/system_mib \ + mibII/tcp \ + mibII/udp \ + mibII/vacm_context \ + mibII/vacm_vars \ + snmpv3/snmpEngine \ + snmpv3/snmpMPDStats \ + snmpv3/usmConf \ + snmpv3/usmStats \ + snmpv3/usmUser \ + tunnel \ + ucd-snmp/disk_hw \ + ucd-snmp/dlmod \ + ucd-snmp/extensible \ + ucd-snmp/loadave \ + ucd-snmp/memory \ + ucd-snmp/pass \ + ucd-snmp/pass_persist \ + ucd-snmp/proc \ + ucd-snmp/vmstat \ + util_funcs \ + utilities/execute \ + +SNMP_MIB_MODULES_EXCLUDED = \ + agent_mibs \ + disman/event \ + disman/schedule \ + hardware \ + host \ + if-mib \ + ip-mib \ + mibII \ + notification \ + notification-log-mib \ + snmpv3mibs \ + target \ + tcp-mib \ + ucd_snmp \ + udp-mib \ + utilities \ + +SNMP_TRANSPORTS_INCLUDED = Callback UDP Unix + +SNMP_TRANSPORTS_EXCLUDED = TCP TCPIPv6 + +TARGET_CFLAGS += $(FPIC) +TARGET_CPPFLAGS += -I$(STAGING_DIR)/usr/include/libnl-tiny + +CONFIGURE_ARGS += \ + --enable-mfd-rewrites \ + --enable-shared \ + --enable-static \ + --with-endianness=$(if $(CONFIG_BIG_ENDIAN),big,little) \ + --with-logfile=/var/log/snmpd.log \ + --with-persistent-directory=/usr/lib/snmp/ \ + --with-default-snmp-version=1 \ + --with-sys-contact=root@localhost \ + --with-sys-location=Unknown \ + --enable-applications \ + --disable-debugging \ + --disable-manuals \ + --disable-scripts \ + --with-out-mib-modules="$(SNMP_MIB_MODULES_EXCLUDED)" \ + --with-mib-modules="$(SNMP_MIB_MODULES_INCLUDED)" \ + --with-out-transports="$(SNMP_TRANSPORTS_EXCLUDED)" \ + --with-transports="$(SNMP_TRANSPORTS_INCLUDED)" \ + --without-openssl \ + --without-libwrap \ + --without-mysql \ + --without-rpm \ + --without-zlib \ + --with-pcre2-8 \ + --with-nl \ + $(call autoconf_bool,CONFIG_IPV6,ipv6) \ + --disable-perl-cc-checks \ + --disable-embedded-perl \ + --without-perl-modules + +CONFIGURE_VARS += \ + ac_cv_header_netlink_netlink_h=yes \ + netsnmp_cv_func_nl_connect_LIBS=-lnl-tiny \ + +ifeq ($(CONFIG_IPV6),y) +SNMP_TRANSPORTS_INCLUDED+= UDPIPv6 +endif + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR) \ + INSTALL_PREFIX="$(PKG_INSTALL_DIR)" \ + LDFLAGS="$(TARGET_LDFLAGS) -lm -lc" \ + all install +endef + +define Build/InstallDev + $(INSTALL_DIR) $(2)/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/net-snmp-config $(2)/bin/ + $(SED) 's,=/usr,=$(STAGING_DIR)/usr,g' $(2)/bin/net-snmp-config + $(INSTALL_DIR) $(STAGING_DIR)/usr/bin + $(LN) $(STAGING_DIR)/host/bin/net-snmp-config $(STAGING_DIR)/usr/bin/ + + $(INSTALL_DIR) $(1)/usr/include + $(CP) $(PKG_INSTALL_DIR)/usr/include/net-snmp $(1)/usr/include/ + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnetsnmp{,agent,helpers,mibs}.{a,so*} $(1)/usr/lib/ +endef + +define Package/libnetsnmp-ssl/install + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnetsnmp{,agent,helpers,mibs}.so.* $(1)/usr/lib/ +endef + +define Package/snmp-mibs-ssl/install + $(INSTALL_DIR) $(1)/usr/share/snmp/mibs + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/snmp/mibs/* $(1)/usr/share/snmp/mibs/ +endef + +define Package/snmp-utils-ssl/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/snmp{get,set,status,test,trap,walk} $(1)/usr/bin/ +endef + +define Package/snmpd-ssl/install + $(INSTALL_DIR) $(1)/etc/snmp + $(LN) /var/run/snmpd.conf $(1)/etc/snmp/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/snmpd.init $(1)/etc/init.d/snmpd + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/snmpd $(1)/usr/sbin/snmpd +endef + +define Package/snmptrapd-ssl/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/snmptrapd.init $(1)/etc/init.d/snmptrapd + $(INSTALL_DIR) $(1)/usr/lib + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libnetsnmptrapd.so.* $(1)/usr/lib/ + $(INSTALL_DIR) $(1)/usr/sbin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/snmptrapd $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,libnetsnmp-ssl)) +$(eval $(call BuildPackage,snmp-mibs-ssl)) +$(eval $(call BuildPackage,snmp-utils-ssl)) +$(eval $(call BuildPackage,snmpd-ssl)) +$(eval $(call BuildPackage,snmpd-static-ssl)) +$(eval $(call BuildPackage,snmptrapd-ssl)) diff --git a/net-snmp-ssl/files/snmpd.init b/net-snmp-ssl/files/snmpd.init new file mode 100644 index 00000000..ca4ff458 --- /dev/null +++ b/net-snmp-ssl/files/snmpd.init @@ -0,0 +1,417 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2008 OpenWrt.org +START=99 + +USE_PROCD=1 +PROG="/usr/sbin/snmpd" + +CONFIGFILE="/var/run/snmpd.conf" +CONFIGFILE2="/usr/lib/snmp/snmpd.conf" + +snmpd_agent_add() { + local cfg="$1" + + config_get agentaddress "$cfg" agentaddress + [ -n "$agentaddress" ] || return 0 + echo "agentaddress $agentaddress" >> $CONFIGFILE +} + +snmpd_agentx_add() { + local cfg="$1" + echo "master agentx" >> $CONFIGFILE + config_get agentxsocket "$cfg" agentxsocket + [ -n "$agentxsocket" ] && echo "agentXSocket $agentxsocket" >> $CONFIGFILE +} + +snmpd_system_add() { + local cfg="$1" + config_get syslocation "$cfg" sysLocation + [ -n "$syslocation" ] && echo "sysLocation $syslocation" >> $CONFIGFILE + config_get syscontact "$cfg" sysContact + [ -n "$syscontact" ] && echo "sysContact $syscontact" >> $CONFIGFILE + config_get sysname "$cfg" sysName + [ -n "$sysname" ] && echo "sysName $sysname" >> $CONFIGFILE + config_get sysservice "$cfg" sysService + [ -n "$sysservice" ] && echo "sysService $sysservice" >> $CONFIGFILE + config_get sysdescr "$cfg" sysDescr + [ -n "$sysdescr" ] && echo "sysDescr $sysdescr" >> $CONFIGFILE + config_get sysobjectid "$cfg" sysObjectID + [ -n "$sysobjectid" ] && echo "sysObjectID $sysobjectid" >> $CONFIGFILE +} + +snmpd_com2sec_add() { + local cfg="$1" + config_get secname "$cfg" secname + [ -n "$secname" ] || return 0 + config_get source "$cfg" source + [ -n "$source" ] || return 0 + config_get community "$cfg" community + [ -n "$community" ] || return 0 + echo "com2sec $secname $source $community" >> $CONFIGFILE +} + +snmpd_com2sec6_add() { + local cfg="$1" + config_get secname "$cfg" secname + [ -n "$secname" ] || return 0 + config_get source "$cfg" source + [ -n "$source" ] || return 0 + config_get community "$cfg" community + [ -n "$community" ] || return 0 + echo "com2sec6 $secname $source $community" >> $CONFIGFILE +} + +snmpd_group_add() { + local cfg="$1" + config_get group "$cfg" group + [ -n "$group" ] || return 0 + config_get version "$cfg" version + [ -n "$version" ] || return 0 + config_get secname "$cfg" secname + [ -n "$secname" ] || return 0 + echo "group $group $version $secname" >> $CONFIGFILE +} + +snmpd_view_add() { + local cfg="$1" + config_get viewname "$cfg" viewname + [ -n "$viewname" ] || return 0 + config_get type "$cfg" type + [ -n "$type" ] || return 0 + config_get oid "$cfg" oid + [ -n "$oid" ] || return 0 + # optional mask + config_get mask "$cfg" mask + echo "view $viewname $type $oid $mask" >> $CONFIGFILE +} + +snmpd_access_add() { + local cfg="$1" + config_get group "$cfg" group + [ -n "$group" ] || return 0 + config_get context "$cfg" context + [ -n $context ] || return 0 + [ "$context" == "none" ] && context='""' + config_get version "$cfg" version + [ -n "$version" ] || return 0 + config_get level "$cfg" level + [ -n "$level" ] || return 0 + config_get prefix "$cfg" prefix + [ -n "$prefix" ] || return 0 + config_get read "$cfg" read + [ -n "$read" ] || return 0 + config_get write "$cfg" write + [ -n "$write" ] || return 0 + config_get notify "$cfg" notify + [ -n "$notify" ] || return 0 + echo "access $group $context $version $level $prefix $read $write $notify" >> $CONFIGFILE +} + +snmpd_trap_hostname_add() { + local cfg="$1" + config_get hostname "$cfg" HostName + config_get port "$cfg" Port + config_get community "$cfg" Community + config_get type "$cfg" Type + echo "$type $hostname $community $port" >> $CONFIGFILE +} + +snmpd_trap_ip_add() { + local cfg="$1" + config_get host_ip "$cfg" HostIP + config_get port "$cfg" Port + config_get community "$cfg" Community + config_get type "$cfg" Type + echo "$type $host_ip $community $port" >> $CONFIGFILE +} + +snmpd_access_default_add() { + local cfg="$1" + config_get mode "$cfg" Mode + config_get community "$cfg" CommunityName + config_get oidrestrict "$cfg" RestrictOID + config_get oid "$cfg" RestrictedOID + echo -n "$mode $community default" >> $CONFIGFILE + [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE + [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE +} + +snmpd_access_HostName_add() { + local cfg="$1" + config_get hostname "$cfg" HostName + config_get mode "$cfg" Mode + config_get community "$cfg" CommunityName + config_get oidrestrict "$cfg" RestrictOID + config_get oid "$cfg" RestrictedOID + echo -n "$mode $community $hostname" >> $CONFIGFILE + [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE + [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE +} + +snmpd_access_HostIP_add() { + local cfg="$1" + config_get host_ip "$cfg" HostIP + config_get ip_mask "$cfg" IPMask + config_get mode "$cfg" Mode + config_get community "$cfg" CommunityName + config_get oidrestrict "$cfg" RestrictOID + config_get oid "$cfg" RestrictedOID + echo -n "$mode $community $host_ip/$ip_mask" >> $CONFIGFILE + [ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE + [ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE +} + +snmpd_pass_add() { + local cfg="$1" + local pass='pass' + + config_get miboid "$cfg" miboid + [ -n "$miboid" ] || return 0 + config_get prog "$cfg" prog + [ -n "$prog" ] || return 0 + config_get_bool persist "$cfg" persist 0 + [ $persist -ne 0 ] && pass='pass_persist' + config_get priority "$cfg" priority + priority=${priority:+-p $priority} + echo "$pass $priority $miboid $prog" >> $CONFIGFILE +} + +snmpd_exec_add() { + local cfg="$1" + + config_get name "$cfg" name + [ -n "$name" ] || return 0 + config_get prog "$cfg" prog + [ -n "$prog" ] || return 0 + config_get args "$cfg" args + config_get miboid "$cfg" miboid + echo "exec $miboid $name $prog $args" >> $CONFIGFILE +} + +snmpd_extend_add() { + local cfg="$1" + + config_get name "$cfg" name + [ -n "$name" ] || return 0 + config_get prog "$cfg" prog + [ -n "$prog" ] || return 0 + config_get args "$cfg" args + config_get miboid "$cfg" miboid + echo "extend $miboid $name $prog $args" >> $CONFIGFILE +} + +snmpd_disk_add() { + local cfg="$1" + local disk='disk' + + config_get partition "$cfg" partition + [ -n "$partition" ] || return 0 + config_get size "$cfg" size + [ -n "$size" ] || return 0 + echo "$disk $partition $size" >> $CONFIGFILE +} + +snmpd_engineid_add() { + local cfg="$1" + + config_get engineid "$cfg" engineid + [ -n "$engineid" ] && echo "engineID $engineid" >> $CONFIGFILE + config_get engineidtype "$cfg" engineidtype + [ "$engineidtype" -ge 1 -a "$engineidtype" -le 3 ] && \ + echo "engineIDType $engineidtype" >> $CONFIGFILE + config_get engineidnic "$cfg" engineidnic + [ -n "$engineidnic" ] && echo "engineIDNic $engineidnic" >> $CONFIGFILE +} + +snmpd_sink_add() { + local cfg="$1" + local section="$2" + local community + local port + local host + + config_get host "$cfg" host + [ -n "section" -a -n "$host" ] || return 0 + # optional community + config_get community "$cfg" community + # optional port + config_get port "$cfg" port + port=${port:+:$port} + echo "$section $host$port $community" >> $CONFIGFILE +} + +append_parm() { + local section="$1" + local option="$2" + local switch="$3" + local _loctmp + config_get _loctmp "$section" "$option" + [ -z "$_loctmp" ] && return 0 + echo "$switch $_loctmp" >> $CONFIGFILE +} + +append_authtrapenable() { + local section="$1" + local option="$2" + local switch="$3" + local _loctmp + config_get_bool _loctmp "$section" "$option" + [ -z "$_loctmp" ] && return 0 + [ "$_loctmp" -gt 0 ] && echo "$switch $_loctmp" >> $CONFIGFILE +} + +snmpd_setup_fw_rules() { + local net="$1" + local zone + + zone=$(fw3 -q network "$net" 2>/dev/null) + + local handled_zone + for handled_zone in $HANDLED_SNMP_ZONES; do + [ "$handled_zone" = "$zone" ] && return + done + + json_add_object "" + json_add_string type rule + json_add_string src "$zone" + json_add_string proto udp + json_add_string dest_port 161 + json_add_string target ACCEPT + json_close_object + + HANDLED_SNMP_ZONES="$HANDLED_SNMP_ZONES $zone" +} + +snmpd_v3_add() { + local section="$1" + config_get mode "$section" mode + if [[ "$mode" != "v1_v2c_v3" ]] && [[ "$mode" != "v3" ]]; then + return + fi + config_get security_name "$section" security_name + [ -n "$security_name" ] || return + config_get security_type "$section" security_type + [ -n "$security_type" ] || return + config_get v3_mode "$section" v3_mode + [ -n "$v3_mode" ] || return + config_get auth_prot "$section" auth_prot + config_get auth_pass "$section" auth_pass + config_get priv_prot "$section" priv_prot + config_get priv_pass "$section" priv_pass + case "$security_type" in + "noAuthNoPriv" ) + echo "createUser $security_name" >> $CONFIGFILE + echo "$v3_mode $security_name noauth" >> $CONFIGFILE + ;; + "authNoPriv" ) + if [[ -z "$auth_prot" ]] || [[ -z "$auth_pass" ]]; then + return + fi + echo "createUser $security_name $auth_prot \"$auth_pass\"" >> $CONFIGFILE + echo "$v3_mode $security_name auth" >> $CONFIGFILE + ;; + "authPriv" ) + if [[ -z "$auth_prot" ]] || [[ -z "$auth_pass" ]]; then + return + fi + if [[ -z "$priv_prot" ]] || [[ -z "$priv_pass" ]]; then + return + fi + echo "createUser $security_name $auth_prot \"$auth_pass\" $priv_prot \"$priv_pass\"" >> $CONFIGFILE + echo "$v3_mode $security_name priv" >> $CONFIGFILE + ;; + esac +} + +start_service() { + [ -f "$CONFIGFILE" ] && rm -f "$CONFIGFILE" + [ -f "$CONFIGFILE2" ] && sed -i '/usmUser/d' "$CONFIGFILE2" + + config_load snmpd + + config_get_bool snmp_enabled general enabled 1 + [ "$snmp_enabled" -eq 0 ] && return + + config_get ip_family general ip_family + config_get mode general mode + + procd_open_instance + + config_foreach snmpd_agent_add agent + config_foreach snmpd_agentx_add agentx + config_foreach snmpd_system_add system + if [[ "$mode" == "v1_v2c_v3" ]] || [[ "$mode" == "v1_v2c" ]]; then + if [[ "$ip_family" == "ipv4" || "$ip_family" == "both" ]]; then + config_foreach snmpd_com2sec_add com2sec + fi + if [[ "$ip_family" == "ipv6" || "$ip_family" == "both" ]]; then + config_foreach snmpd_com2sec6_add com2sec6 + fi + fi + config_foreach snmpd_group_add group + config_foreach snmpd_view_add view + config_foreach snmpd_access_add access + config_foreach snmpd_trap_hostname_add trap_HostName + config_foreach snmpd_trap_ip_add trap_HostIP + config_foreach snmpd_access_default_add access_default + config_foreach snmpd_access_HostName_add access_HostName + config_foreach snmpd_access_HostIP_add access_HostIP + config_foreach snmpd_pass_add pass + config_foreach snmpd_exec_add exec + config_foreach snmpd_extend_add extend + config_foreach snmpd_disk_add disk + config_foreach snmpd_engineid_add engineid + append_parm trapcommunity community trapcommunity + config_foreach snmpd_sink_add trapsink trapsink + config_foreach snmpd_sink_add trap2sink trap2sink + config_foreach snmpd_sink_add informsink informsink + config_foreach snmpd_v3_add snmpd + append_authtrapenable authtrapenable enable authtrapenable + append_parm v1trapaddress host v1trapaddress + append_parm trapsess trapsess trapsess + + procd_set_param command $PROG -Lf /dev/null -f -r + procd_set_param file $CONFIGFILE + procd_set_param respawn + + for iface in $(ls /sys/class/net 2>/dev/null); do + procd_append_param netdev "$iface" + done + + procd_open_data + + json_add_array firewall + config_list_foreach general network snmpd_setup_fw_rules + json_close_array + + procd_close_data + + procd_close_instance +} + +stop_service() { + [ -f "$CONFIGFILE" ] || return + rm -f "$CONFIGFILE" + procd_set_config_changed firewall +} + +reload_service() { + stop + start +} + +service_triggers(){ + local script=$(readlink "$initscript") + local name=$(basename ${script:-$initscript}) + + procd_open_trigger + procd_add_raw_trigger "interface.*" 2000 /etc/init.d/$name reload + procd_close_trigger + + procd_add_reload_trigger 'snmpd' +} + +service_started() { + [ "$snmp_enabled" -eq 0 ] && return + procd_set_config_changed firewall +} diff --git a/net-snmp-ssl/files/snmptrapd.init b/net-snmp-ssl/files/snmptrapd.init new file mode 100644 index 00000000..43278a2f --- /dev/null +++ b/net-snmp-ssl/files/snmptrapd.init @@ -0,0 +1,15 @@ +#!/bin/sh /etc/rc.common + +START=50 + +USE_PROCD=1 +PROG="/usr/sbin/snmptrapd" + +start_service() { + procd_open_instance + + procd_set_param command $PROG -Lf /dev/null -f + procd_set_param respawn + + procd_close_instance +} diff --git a/net-snmp-ssl/patches/000-cross-compile.patch b/net-snmp-ssl/patches/000-cross-compile.patch new file mode 100644 index 00000000..b0c9f4d5 --- /dev/null +++ b/net-snmp-ssl/patches/000-cross-compile.patch @@ -0,0 +1,47 @@ +From: Jo-Philipp Wich +Date: Fri, 6 Jan 2017 13:41:00 +0100 +Subject: [PATCH] configure: allow overriding hardcoded /usr/include/libnl3 + +In a cross-compile setting we do not want to probe the host systems +/usr/include path, therfore allow to disable this include path by passing +ac_cv_header_netlink_netlink_h=yes to configure. + +Also disable the testing for libraries providing nl_connect when +netsnmp_cv_func_nl_connect_LIBS is predefined since the proprietary +NETSNMP_SEARCH_LIBS() macro will clobber the internal link flags upon +encountering predefined cache variables, causing all subsequent configure +link tests to fail due to a stray "no" word getting passed to the linker. + +Signed-off-by: Jo-Philipp Wich +--- a/configure.d/config_os_libs2 ++++ b/configure.d/config_os_libs2 +@@ -252,14 +252,22 @@ if test "x$with_nl" != "xno"; then + case $target_os in + linux*) # Check for libnl (linux) + netsnmp_save_CPPFLAGS="$CPPFLAGS" +- CPPFLAGS="${LIBNL3_CFLAGS} ${LIBNLROUTE3_CFLAGS} $CPPFLAGS" +- NETSNMP_SEARCH_LIBS(nl_connect, nl-3, +- [AC_CHECK_HEADERS(netlink/netlink.h) +- EXTERNAL_MIBGROUP_INCLUDES="$EXTERNAL_MIBGROUP_INCLUDES ${LIBNL3_CFLAGS}"], +- [CPPFLAGS="$netsnmp_save_CPPFLAGS"], [], [LMIBLIBS]) ++ netsnmp_netlink_include_flags="" + if test "x$ac_cv_header_netlink_netlink_h" != xyes; then +- NETSNMP_SEARCH_LIBS(nl_connect, nl, [ +- AC_CHECK_HEADERS(netlink/netlink.h)], [], [], LMIBLIBS) ++ netsnmp_netlink_include_flags="-I/usr/include/libnl3" ++ fi ++ CPPFLAGS="$netsnmp_netlink_include_flags $CPPFLAGS" ++ if test "x$netsnmp_cv_func_nl_connect_LIBS" = x; then ++ NETSNMP_SEARCH_LIBS(nl_connect, nl-3, ++ [AC_CHECK_HEADERS(netlink/netlink.h) ++ EXTERNAL_MIBGROUP_INCLUDES="$EXTERNAL_MIBGROUP_INCLUDES $netsnmp_netlink_include_flags"], ++ [CPPFLAGS="$netsnmp_save_CPPFLAGS"], [], [], [LMIBLIBS]) ++ if test "x$ac_cv_header_netlink_netlink_h" != xyes; then ++ NETSNMP_SEARCH_LIBS(nl_connect, nl, [ ++ AC_CHECK_HEADERS(netlink/netlink.h)], [], [], LMIBLIBS) ++ fi ++ else ++ LMIBLIBS="$LMIBLIBS $netsnmp_cv_func_nl_connect_LIBS" + fi + if test "x$ac_cv_header_netlink_netlink_h" = xyes; then + AC_EGREP_HEADER([nl_socket_free], [netlink/socket.h], diff --git a/net-snmp-ssl/patches/010-HOST-MIB-hr_filesys-fix-compile-error.patch b/net-snmp-ssl/patches/010-HOST-MIB-hr_filesys-fix-compile-error.patch new file mode 100644 index 00000000..98ca9538 --- /dev/null +++ b/net-snmp-ssl/patches/010-HOST-MIB-hr_filesys-fix-compile-error.patch @@ -0,0 +1,34 @@ +From 9588b5c9c27239b1f8c02f0bf417f13735e93225 Mon Sep 17 00:00:00 2001 +From: Stijn Tintel +Date: Sat, 26 Sep 2020 04:34:18 +0300 +Subject: [PATCH] HOST-MIB, hr_filesys: fix compile error + +On non-AIX systems without getfsstat, a variable is being declared right +after a label. This is a violation of the C language standard, and +causes the following compile error: + +host/hr_filesys.c: In function 'Get_Next_HR_FileSys': +host/hr_filesys.c:752:5: error: a label can only be part of a statement and a declaration is not a statement + const char **cpp; + ^~~~~ + +Fix the problem by adding an empty statement after the label. + +Fixes: 22e1371bb1fd ("HOST-MIB, hr_filesys: Convert recursion into iteration") + +Signed-off-by: Stijn Tintel +--- + agent/mibgroup/host/hr_filesys.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/agent/mibgroup/host/hr_filesys.c ++++ b/agent/mibgroup/host/hr_filesys.c +@@ -718,7 +718,7 @@ static const char *HRFS_ignores[] = { + int + Get_Next_HR_FileSys(void) + { +-next: ++next: ; + #ifdef HAVE_GETFSSTAT + if (HRFS_index >= fscount) + return -1; diff --git a/net-snmp-ssl/patches/100-debian-statistics.patch b/net-snmp-ssl/patches/100-debian-statistics.patch new file mode 100644 index 00000000..7f8f9df8 --- /dev/null +++ b/net-snmp-ssl/patches/100-debian-statistics.patch @@ -0,0 +1,13 @@ +--- a/agent/mibgroup/mibII/interfaces.c ++++ b/agent/mibgroup/mibII/interfaces.c +@@ -1586,6 +1586,10 @@ Interface_Scan_Init(void) + char *stats, *ifstart = line; + size_t len; + ++ /* Ignore interfaces with no statistics. */ ++ if (strstr(line, "No statistics available.")) ++ continue; ++ + len = strlen(line); + if (len && line[len - 1] == '\n') + line[len - 1] = '\0'; diff --git a/net-snmp-ssl/patches/110-debian-makefiles.patch b/net-snmp-ssl/patches/110-debian-makefiles.patch new file mode 100644 index 00000000..2cb2715a --- /dev/null +++ b/net-snmp-ssl/patches/110-debian-makefiles.patch @@ -0,0 +1,40 @@ +--- a/local/Makefile.in ++++ b/local/Makefile.in +@@ -101,7 +101,7 @@ tkmib.made: $(srcdir)/tkmib + + mib2c.made: $(srcdir)/mib2c + if test "x$(PERL)" != "x" ; then \ +- $(PERL) -p -e 's%^#!.*/perl.*%#!$(PERL)%;s#/usr/local/share/snmp#$(snmplibdir)#;' ${srcdir}/mib2c > mib2c.made; \ ++ $(PERL) -p -e 's%^#!.*/perl.*%#!$(PERL)%;s#/usr/local/share/snmp#$(snmplibdir)#;s#/usr/local/etc/snmp#$(SNMPCONFPATH)#;' ${srcdir}/mib2c > mib2c.made; \ + else \ + touch mib2c.made; \ + fi +--- a/Makefile.top ++++ b/Makefile.top +@@ -28,6 +28,7 @@ man8dir = $(mandir)/man8 + snmplibdir = $(datadir)/snmp + mibdir = $(snmplibdir)/mibs + persistentdir = @PERSISTENT_DIRECTORY@ ++sysconfdir = @sysconfdir@ + DESTDIR = @INSTALL_PREFIX@ + INSTALL_PREFIX = $(DESTDIR) + +--- a/mibs/Makefile.in ++++ b/mibs/Makefile.in +@@ -47,11 +47,15 @@ NETSNMPMIBS = NET-SNMP-TC.txt NET-SNMP-M + UCDMIBS = UCD-SNMP-MIB.txt UCD-DEMO-MIB.txt UCD-IPFWACC-MIB.txt \ + UCD-DLMOD-MIB.txt UCD-DISKIO-MIB.txt + ++EXTRAMIBS = BGP4-MIB.txt BRIDGE-MIB.txt GNOME-SMI.txt OSPF-MIB.txt \ ++ OSPF-TRAP-MIB.txt RIPv2-MIB.txt SOURCE-ROUTING-MIB.txt \ ++ LM-SENSORS-MIB.txt ++ + DEFAULTMIBS = @default_mibs_install@ + + MIBS = $(V1MIBS) $(V2MIBS) $(V3MIBS) $(RFCMIBS) \ + $(AGENTMIBS) $(IANAMIBS) \ +- $(NETSNMPMIBS) $(UCDMIBS) $(DEFAULTMIBS) ++ $(NETSNMPMIBS) $(UCDMIBS) $(DEFAULTMIBS) $(EXTRAMIBS) + + all: standardall + diff --git a/net-snmp-ssl/patches/120-debian-searchdirs.patch b/net-snmp-ssl/patches/120-debian-searchdirs.patch new file mode 100644 index 00000000..b5e377f9 --- /dev/null +++ b/net-snmp-ssl/patches/120-debian-searchdirs.patch @@ -0,0 +1,14 @@ +--- a/local/mib2c ++++ b/local/mib2c +@@ -61,8 +61,9 @@ $currentlevel = -1; + if($ENV{MIB2C_DIR}) { + push @def_search_dirs, split(/:/, $ENV{MIB2C_DIR}); + } +-push @def_search_dirs, "/usr/local/share/snmp/"; +-push @def_search_dirs, "/usr/local/share/snmp/mib2c-data"; ++push @def_search_dirs, "/etc/snmp/"; ++push @def_search_dirs, "/usr/share/snmp/"; ++push @def_search_dirs, "/usr/share/snmp/mib2c-data"; + push @def_search_dirs, "./mib2c-conf.d"; + + sub usage { diff --git a/net-snmp-ssl/patches/130-debian-extramibs.patch b/net-snmp-ssl/patches/130-debian-extramibs.patch new file mode 100644 index 00000000..48fb9074 --- /dev/null +++ b/net-snmp-ssl/patches/130-debian-extramibs.patch @@ -0,0 +1,5183 @@ +--- /dev/null ++++ b/mibs/BGP4-MIB.txt +@@ -0,0 +1,929 @@ ++ BGP4-MIB DEFINITIONS ::= BEGIN ++ ++ IMPORTS ++ MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, ++ IpAddress, Integer32, Counter32, Gauge32, mib-2 ++ FROM SNMPv2-SMI ++ MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP ++ FROM SNMPv2-CONF; ++ ++ bgp MODULE-IDENTITY ++ LAST-UPDATED "9902100000Z" ++ ORGANIZATION "IETF IDR Working Group" ++ CONTACT-INFO "E-mail: idr@merit.net ++ ++ Susan Hares (Editor) ++ Merit Network ++ 4251 Plymouth Road ++ Suite C ++ Ann Arbor, MI 48105-2785 ++ Tel: +1 734 936 2095 ++ Fax: +1 734 647 3185 ++ E-mail: skh@merit.edu ++ ++ Jeff Johnson (Editor) ++ RedBack Networks, Inc. ++ 1389 Moffett Park Drive ++ Sunnyvale, CA 94089-1134 ++ Tel: +1 408 548 3516 ++ Fax: +1 408 548 3599 ++ E-mail: jeff@redback.com" ++ DESCRIPTION ++ "The MIB module for BGP-4." ++ REVISION "9902100000Z" ++ DESCRIPTION ++ "Corrected duplicate OBJECT IDENTIFIER ++ assignment in the conformance information." ++ REVISION "9601080000Z" ++ DESCRIPTION ++ "1) Fixed the definitions of the traps to ++ make them equivalent to their initial ++ definition in RFC 1269. ++ 2) Added compliance and conformance info." ++ ::= { mib-2 15 } ++ ++ bgpVersion OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE (1..255)) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "Vector of supported BGP protocol version ++ numbers. Each peer negotiates the version ++ from this vector. Versions are identified ++ via the string of bits contained within this ++ object. The first octet contains bits 0 to ++ 7, the second octet contains bits 8 to 15, ++ and so on, with the most significant bit ++ referring to the lowest bit number in the ++ octet (e.g., the MSB of the first octet ++ refers to bit 0). If a bit, i, is present ++ and set, then the version (i+1) of the BGP ++ is supported." ++ ::= { bgp 1 } ++ ++ bgpLocalAs OBJECT-TYPE ++ SYNTAX INTEGER (0..65535) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The local autonomous system number." ++ ::= { bgp 2 } ++ ++ ++ ++ -- BGP Peer table. This table contains, one entry per BGP ++ -- peer, information about the BGP peer. ++ ++ bgpPeerTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF BgpPeerEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "BGP peer table. This table contains, ++ one entry per BGP peer, information about the ++ connections with BGP peers." ++ ::= { bgp 3 } ++ ++ bgpPeerEntry OBJECT-TYPE ++ SYNTAX BgpPeerEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "Entry containing information about the ++ connection with a BGP peer." ++ INDEX { bgpPeerRemoteAddr } ++ ::= { bgpPeerTable 1 } ++ ++ BgpPeerEntry ::= SEQUENCE { ++ bgpPeerIdentifier ++ IpAddress, ++ bgpPeerState ++ INTEGER, ++ bgpPeerAdminStatus ++ INTEGER, ++ bgpPeerNegotiatedVersion ++ Integer32, ++ bgpPeerLocalAddr ++ IpAddress, ++ bgpPeerLocalPort ++ INTEGER, ++ bgpPeerRemoteAddr ++ IpAddress, ++ bgpPeerRemotePort ++ INTEGER, ++ bgpPeerRemoteAs ++ INTEGER, ++ bgpPeerInUpdates ++ Counter32, ++ bgpPeerOutUpdates ++ Counter32, ++ bgpPeerInTotalMessages ++ Counter32, ++ bgpPeerOutTotalMessages ++ Counter32, ++ bgpPeerLastError ++ OCTET STRING, ++ bgpPeerFsmEstablishedTransitions ++ Counter32, ++ bgpPeerFsmEstablishedTime ++ Gauge32, ++ bgpPeerConnectRetryInterval ++ INTEGER, ++ bgpPeerHoldTime ++ INTEGER, ++ bgpPeerKeepAlive ++ INTEGER, ++ bgpPeerHoldTimeConfigured ++ INTEGER, ++ bgpPeerKeepAliveConfigured ++ INTEGER, ++ bgpPeerMinASOriginationInterval ++ INTEGER, ++ bgpPeerMinRouteAdvertisementInterval ++ INTEGER, ++ bgpPeerInUpdateElapsedTime ++ Gauge32 ++ } ++ ++ bgpPeerIdentifier OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The BGP Identifier of this entry's BGP peer." ++ ::= { bgpPeerEntry 1 } ++ ++ bgpPeerState OBJECT-TYPE ++ SYNTAX INTEGER { ++ idle(1), ++ connect(2), ++ active(3), ++ opensent(4), ++ openconfirm(5), ++ established(6) ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The BGP peer connection state." ++ ::= { bgpPeerEntry 2 } ++ ++ bgpPeerAdminStatus OBJECT-TYPE ++ SYNTAX INTEGER { ++ stop(1), ++ start(2) ++ } ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "The desired state of the BGP connection. A ++ transition from 'stop' to 'start' will cause ++ the BGP Start Event to be generated. A ++ transition from 'start' to 'stop' will cause ++ the BGP Stop Event to be generated. This ++ parameter can be used to restart BGP peer ++ connections. Care should be used in providing ++ write access to this object without adequate ++ authentication." ++ ::= { bgpPeerEntry 3 } ++ ++ bgpPeerNegotiatedVersion OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The negotiated version of BGP running between ++ the two peers." ++ ::= { bgpPeerEntry 4 } ++ ++ bgpPeerLocalAddr OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The local IP address of this entry's BGP ++ connection." ++ ::= { bgpPeerEntry 5 } ++ ++ bgpPeerLocalPort OBJECT-TYPE ++ SYNTAX INTEGER (0..65535) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The local port for the TCP connection between ++ the BGP peers." ++ ::= { bgpPeerEntry 6 } ++ ++ bgpPeerRemoteAddr OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The remote IP address of this entry's BGP ++ peer." ++ ::= { bgpPeerEntry 7 } ++ ++ bgpPeerRemotePort OBJECT-TYPE ++ SYNTAX INTEGER (0..65535) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The remote port for the TCP connection between ++ the BGP peers. Note that the objects ++ bgpPeerLocalAddr, bgpPeerLocalPort, ++ bgpPeerRemoteAddr and bgpPeerRemotePort ++ provide the appropriate reference to the ++ standard MIB TCP connection table." ++ ::= { bgpPeerEntry 8 } ++ ++ bgpPeerRemoteAs OBJECT-TYPE ++ SYNTAX INTEGER (0..65535) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The remote autonomous system number." ++ ::= { bgpPeerEntry 9 } ++ ++ bgpPeerInUpdates OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of BGP UPDATE messages received on ++ this connection. This object should be ++ initialized to zero (0) when the connection is ++ established." ++ ::= { bgpPeerEntry 10 } ++ ++ bgpPeerOutUpdates OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of BGP UPDATE messages transmitted ++ on this connection. This object should be ++ initialized to zero (0) when the connection is ++ established." ++ ::= { bgpPeerEntry 11 } ++ ++ bgpPeerInTotalMessages OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The total number of messages received from the ++ remote peer on this connection. This object ++ should be initialized to zero when the ++ connection is established." ++ ::= { bgpPeerEntry 12 } ++ ++ bgpPeerOutTotalMessages OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The total number of messages transmitted to ++ the remote peer on this connection. This object ++ should be initialized to zero when the ++ connection is established." ++ ::= { bgpPeerEntry 13 } ++ ++ bgpPeerLastError OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE (2)) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The last error code and subcode seen by this ++ peer on this connection. If no error has ++ occurred, this field is zero. Otherwise, the ++ first byte of this two byte OCTET STRING ++ contains the error code, and the second byte ++ contains the subcode." ++ ::= { bgpPeerEntry 14 } ++ ++ bgpPeerFsmEstablishedTransitions OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The total number of times the BGP FSM ++ transitioned into the established state." ++ ::= { bgpPeerEntry 15 } ++ ++ bgpPeerFsmEstablishedTime OBJECT-TYPE ++ SYNTAX Gauge32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "This timer indicates how long (in seconds) this ++ peer has been in the Established state or how long ++ since this peer was last in the Established state. ++ It is set to zero when a new peer is configured or ++ the router is booted." ++ ::= { bgpPeerEntry 16 } ++ ++ bgpPeerConnectRetryInterval OBJECT-TYPE ++ SYNTAX INTEGER (1..65535) ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "Time interval in seconds for the ConnectRetry ++ timer. The suggested value for this timer is ++ 120 seconds." ++ ::= { bgpPeerEntry 17 } ++ ++ bgpPeerHoldTime OBJECT-TYPE ++ SYNTAX INTEGER ( 0 | 3..65535 ) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "Time interval in seconds for the Hold Timer ++ established with the peer. The value of this ++ object is calculated by this BGP speaker by ++ using the smaller of the value in ++ bgpPeerHoldTimeConfigured and the Hold Time ++ received in the OPEN message. This value ++ must be at lease three seconds if it is not ++ zero (0) in which case the Hold Timer has ++ not been established with the peer, or, the ++ value of bgpPeerHoldTimeConfigured is zero (0)." ++ ::= { bgpPeerEntry 18 } ++ ++ bgpPeerKeepAlive OBJECT-TYPE ++ SYNTAX INTEGER ( 0 | 1..21845 ) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "Time interval in seconds for the KeepAlive ++ timer established with the peer. The value of ++ this object is calculated by this BGP speaker ++ such that, when compared with bgpPeerHoldTime, ++ it has the same proportion as what ++ bgpPeerKeepAliveConfigured has when compared ++ with bgpPeerHoldTimeConfigured. If the value ++ of this object is zero (0), it indicates that ++ the KeepAlive timer has not been established ++ with the peer, or, the value of ++ bgpPeerKeepAliveConfigured is zero (0)." ++ ::= { bgpPeerEntry 19 } ++ ++ bgpPeerHoldTimeConfigured OBJECT-TYPE ++ SYNTAX INTEGER ( 0 | 3..65535 ) ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "Time interval in seconds for the Hold Time ++ configured for this BGP speaker with this peer. ++ This value is placed in an OPEN message sent to ++ this peer by this BGP speaker, and is compared ++ with the Hold Time field in an OPEN message ++ received from the peer when determining the Hold ++ Time (bgpPeerHoldTime) with the peer. This value ++ must not be less than three seconds if it is not ++ zero (0) in which case the Hold Time is NOT to be ++ established with the peer. The suggested value for ++ this timer is 90 seconds." ++ ::= { bgpPeerEntry 20 } ++ ++ bgpPeerKeepAliveConfigured OBJECT-TYPE ++ SYNTAX INTEGER ( 0 | 1..21845 ) ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "Time interval in seconds for the KeepAlive timer ++ configured for this BGP speaker with this peer. ++ The value of this object will only determine the ++ KEEPALIVE messages' frequency relative to the value ++ specified in bgpPeerHoldTimeConfigured; the actual ++ time interval for the KEEPALIVE messages is ++ indicated by bgpPeerKeepAlive. A reasonable ++ maximum value for this timer would be configured to ++ be one third of that of bgpPeerHoldTimeConfigured. ++ If the value of this object is zero (0), no ++ periodical KEEPALIVE messages are sent to the peer ++ after the BGP connection has been established. The ++ suggested value for this timer is 30 seconds." ++ ::= { bgpPeerEntry 21 } ++ ++ bgpPeerMinASOriginationInterval OBJECT-TYPE ++ SYNTAX INTEGER (1..65535) ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "Time interval in seconds for the ++ MinASOriginationInterval timer. ++ The suggested value for this timer is 15 seconds." ++ ::= { bgpPeerEntry 22 } ++ ++ bgpPeerMinRouteAdvertisementInterval OBJECT-TYPE ++ SYNTAX INTEGER (1..65535) ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "Time interval in seconds for the ++ MinRouteAdvertisementInterval timer. ++ The suggested value for this timer is 30 seconds." ++ ::= { bgpPeerEntry 23 } ++ ++ bgpPeerInUpdateElapsedTime OBJECT-TYPE ++ SYNTAX Gauge32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "Elapsed time in seconds since the last BGP ++ UPDATE message was received from the peer. ++ Each time bgpPeerInUpdates is incremented, ++ the value of this object is set to zero (0)." ++ ::= { bgpPeerEntry 24 } ++ ++ ++ ++ bgpIdentifier OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The BGP Identifier of local system." ++ ::= { bgp 4 } ++ ++ ++ ++ -- Received Path Attribute Table. This table contains, ++ -- one entry per path to a network, path attributes ++ -- received from all peers running BGP version 3 or less. ++ -- This table is obsolete, having been replaced in ++ -- functionality with the bgp4PathAttrTable. ++ ++ bgpRcvdPathAttrTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF BgpPathAttrEntry ++ MAX-ACCESS not-accessible ++ STATUS obsolete ++ DESCRIPTION ++ "The BGP Received Path Attribute Table contains ++ information about paths to destination networks ++ received from all peers running BGP version 3 or ++ less." ++ ::= { bgp 5 } ++ ++ bgpPathAttrEntry OBJECT-TYPE ++ SYNTAX BgpPathAttrEntry ++ MAX-ACCESS not-accessible ++ STATUS obsolete ++ DESCRIPTION ++ "Information about a path to a network." ++ INDEX { bgpPathAttrDestNetwork, ++ bgpPathAttrPeer } ++ ::= { bgpRcvdPathAttrTable 1 } ++ ++ BgpPathAttrEntry ::= SEQUENCE { ++ bgpPathAttrPeer ++ IpAddress, ++ bgpPathAttrDestNetwork ++ IpAddress, ++ bgpPathAttrOrigin ++ INTEGER, ++ bgpPathAttrASPath ++ OCTET STRING, ++ bgpPathAttrNextHop ++ IpAddress, ++ bgpPathAttrInterASMetric ++ Integer32 ++ } ++ ++ bgpPathAttrPeer OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS obsolete ++ DESCRIPTION ++ "The IP address of the peer where the path ++ information was learned." ++ ::= { bgpPathAttrEntry 1 } ++ ++ bgpPathAttrDestNetwork OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS obsolete ++ DESCRIPTION ++ "The address of the destination network." ++ ::= { bgpPathAttrEntry 2 } ++ ++ bgpPathAttrOrigin OBJECT-TYPE ++ SYNTAX INTEGER { ++ igp(1),-- networks are interior ++ egp(2),-- networks learned via EGP ++ incomplete(3) -- undetermined ++ } ++ MAX-ACCESS read-only ++ STATUS obsolete ++ DESCRIPTION ++ "The ultimate origin of the path information." ++ ::= { bgpPathAttrEntry 3 } ++ ++ bgpPathAttrASPath OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE (2..255)) ++ MAX-ACCESS read-only ++ STATUS obsolete ++ DESCRIPTION ++ "The set of ASs that must be traversed to reach ++ the network. This object is probably best ++ represented as SEQUENCE OF INTEGER. For SMI ++ compatibility, though, it is represented as ++ OCTET STRING. Each AS is represented as a pair ++ of octets according to the following algorithm: ++ ++ first-byte-of-pair = ASNumber / 256; ++ second-byte-of-pair = ASNumber & 255;" ++ ::= { bgpPathAttrEntry 4 } ++ ++ bgpPathAttrNextHop OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS obsolete ++ DESCRIPTION ++ "The address of the border router that should ++ be used for the destination network." ++ ::= { bgpPathAttrEntry 5 } ++ ++ bgpPathAttrInterASMetric OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS obsolete ++ DESCRIPTION ++ "The optional inter-AS metric. If this ++ attribute has not been provided for this route, ++ the value for this object is 0." ++ ::= { bgpPathAttrEntry 6 } ++ ++ ++ ++ -- BGP-4 Received Path Attribute Table. This table contains, ++ -- one entry per path to a network, path attributes ++ -- received from all peers running BGP-4. ++ ++ bgp4PathAttrTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF Bgp4PathAttrEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "The BGP-4 Received Path Attribute Table contains ++ information about paths to destination networks ++ received from all BGP4 peers." ++ ::= { bgp 6 } ++ ++ bgp4PathAttrEntry OBJECT-TYPE ++ SYNTAX Bgp4PathAttrEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "Information about a path to a network." ++ INDEX { bgp4PathAttrIpAddrPrefix, ++ bgp4PathAttrIpAddrPrefixLen, ++ bgp4PathAttrPeer } ++ ::= { bgp4PathAttrTable 1 } ++ ++ Bgp4PathAttrEntry ::= SEQUENCE { ++ bgp4PathAttrPeer ++ IpAddress, ++ bgp4PathAttrIpAddrPrefixLen ++ INTEGER, ++ bgp4PathAttrIpAddrPrefix ++ IpAddress, ++ bgp4PathAttrOrigin ++ INTEGER, ++ bgp4PathAttrASPathSegment ++ OCTET STRING, ++ bgp4PathAttrNextHop ++ IpAddress, ++ bgp4PathAttrMultiExitDisc ++ INTEGER, ++ bgp4PathAttrLocalPref ++ INTEGER, ++ bgp4PathAttrAtomicAggregate ++ INTEGER, ++ bgp4PathAttrAggregatorAS ++ INTEGER, ++ bgp4PathAttrAggregatorAddr ++ IpAddress, ++ bgp4PathAttrCalcLocalPref ++ INTEGER, ++ bgp4PathAttrBest ++ INTEGER, ++ bgp4PathAttrUnknown ++ OCTET STRING ++ } ++ ++ bgp4PathAttrPeer OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP address of the peer where the path ++ information was learned." ++ ::= { bgp4PathAttrEntry 1 } ++ bgp4PathAttrIpAddrPrefixLen OBJECT-TYPE ++ SYNTAX INTEGER (0..32) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "Length in bits of the IP address prefix in the ++ Network Layer Reachability Information field." ++ ::= { bgp4PathAttrEntry 2 } ++ ++ bgp4PathAttrIpAddrPrefix OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "An IP address prefix in the Network Layer ++ Reachability Information field. This object ++ is an IP address containing the prefix with ++ length specified by bgp4PathAttrIpAddrPrefixLen. ++ Any bits beyond the length specified by ++ bgp4PathAttrIpAddrPrefixLen are zeroed." ++ ::= { bgp4PathAttrEntry 3 } ++ ++ bgp4PathAttrOrigin OBJECT-TYPE ++ SYNTAX INTEGER { ++ igp(1),-- networks are interior ++ egp(2),-- networks learned via EGP ++ incomplete(3) -- undetermined ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The ultimate origin of the path information." ++ ::= { bgp4PathAttrEntry 4 } ++ ++ bgp4PathAttrASPathSegment OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE (2..255)) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The sequence of AS path segments. Each AS ++ path segment is represented by a triple ++ . ++ ++ The type is a 1-octet field which has two ++ possible values: ++ 1 AS_SET: unordered set of ASs a ++ route in the UPDATE message ++ has traversed ++ 2 AS_SEQUENCE: ordered set of ASs ++ a route in the UPDATE message ++ has traversed. ++ ++ The length is a 1-octet field containing the ++ number of ASs in the value field. ++ ++ The value field contains one or more AS ++ numbers, each AS is represented in the octet ++ string as a pair of octets according to the ++ following algorithm: ++ ++ first-byte-of-pair = ASNumber / 256; ++ second-byte-of-pair = ASNumber & 255;" ++ ::= { bgp4PathAttrEntry 5 } ++ ++ bgp4PathAttrNextHop OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The address of the border router that should ++ be used for the destination network." ++ ::= { bgp4PathAttrEntry 6 } ++ ++ bgp4PathAttrMultiExitDisc OBJECT-TYPE ++ SYNTAX INTEGER (-1..2147483647) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "This metric is used to discriminate between ++ multiple exit points to an adjacent autonomous ++ system. A value of -1 indicates the absence of ++ this attribute." ++ ::= { bgp4PathAttrEntry 7 } ++ ++ bgp4PathAttrLocalPref OBJECT-TYPE ++ SYNTAX INTEGER (-1..2147483647) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The originating BGP4 speaker's degree of ++ preference for an advertised route. A value of ++ -1 indicates the absence of this attribute." ++ ::= { bgp4PathAttrEntry 8 } ++ ++ bgp4PathAttrAtomicAggregate OBJECT-TYPE ++ SYNTAX INTEGER { ++ lessSpecificRrouteNotSelected(1), ++ lessSpecificRouteSelected(2) ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "Whether or not a system has selected ++ a less specific route without selecting a ++ more specific route." ++ ::= { bgp4PathAttrEntry 9 } ++ ++ bgp4PathAttrAggregatorAS OBJECT-TYPE ++ SYNTAX INTEGER (0..65535) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The AS number of the last BGP4 speaker that ++ performed route aggregation. A value of zero (0) ++ indicates the absence of this attribute." ++ ::= { bgp4PathAttrEntry 10 } ++ ++ bgp4PathAttrAggregatorAddr OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP address of the last BGP4 speaker that ++ performed route aggregation. A value of ++ 0.0.0.0 indicates the absence of this attribute." ++ ::= { bgp4PathAttrEntry 11 } ++ ++ bgp4PathAttrCalcLocalPref OBJECT-TYPE ++ SYNTAX INTEGER (-1..2147483647) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The degree of preference calculated by the ++ receiving BGP4 speaker for an advertised route. ++ A value of -1 indicates the absence of this ++ attribute." ++ ::= { bgp4PathAttrEntry 12 } ++ ++ bgp4PathAttrBest OBJECT-TYPE ++ SYNTAX INTEGER { ++ false(1),-- not chosen as best route ++ true(2) -- chosen as best route ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "An indication of whether or not this route ++ was chosen as the best BGP4 route." ++ ::= { bgp4PathAttrEntry 13 } ++ ++ bgp4PathAttrUnknown OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE(0..255)) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "One or more path attributes not understood ++ by this BGP4 speaker. Size zero (0) indicates ++ the absence of such attribute(s). Octets ++ beyond the maximum size, if any, are not ++ recorded by this object." ++ ::= { bgp4PathAttrEntry 14 } ++ ++ ++ -- Traps. ++ ++ -- note that in RFC 1657, bgpTraps was incorrectly ++ -- assigned a value of { bgp 7 }, and each of the ++ -- traps had the bgpPeerRemoteAddr object inappropriately ++ -- removed from their OBJECTS clause. The following ++ -- definitions restore the semantics of the traps as ++ -- they were initially defined in RFC 1269. ++ ++ -- { bgp 7 } is unused ++ ++ bgpTraps OBJECT IDENTIFIER ::= { bgp 0 } ++ ++ bgpEstablished NOTIFICATION-TYPE ++ OBJECTS { bgpPeerRemoteAddr, ++ bgpPeerLastError, ++ bgpPeerState } ++ STATUS current ++ DESCRIPTION ++ "The BGP Established event is generated when ++ the BGP FSM enters the ESTABLISHED state." ++ ::= { bgpTraps 1 } ++ ++ bgpBackwardTransition NOTIFICATION-TYPE ++ OBJECTS { bgpPeerRemoteAddr, ++ bgpPeerLastError, ++ bgpPeerState } ++ STATUS current ++ DESCRIPTION ++ "The BGPBackwardTransition Event is generated ++ when the BGP FSM moves from a higher numbered ++ state to a lower numbered state." ++ ::= { bgpTraps 2 } ++ ++ -- conformance information ++ ++ bgpMIBConformance OBJECT IDENTIFIER ::= { bgp 8 } ++ bgpMIBCompliances OBJECT IDENTIFIER ::= { bgpMIBConformance 1 } ++ bgpMIBGroups OBJECT IDENTIFIER ::= { bgpMIBConformance 2 } ++ ++ -- compliance statements ++ ++ bgpMIBCompliance MODULE-COMPLIANCE ++ STATUS current ++ DESCRIPTION ++ "The compliance statement for entities which ++ implement the BGP4 mib." ++ MODULE -- this module ++ MANDATORY-GROUPS { bgp4MIBGlobalsGroup, ++ bgp4MIBPeerGroup, ++ bgp4MIBPathAttrGroup, ++ bgp4MIBNotificationGroup } ++ ::= { bgpMIBCompliances 1 } ++ ++ -- units of conformance ++ ++ bgp4MIBGlobalsGroup OBJECT-GROUP ++ OBJECTS { bgpVersion, ++ bgpLocalAs, ++ bgpIdentifier } ++ STATUS current ++ DESCRIPTION ++ "A collection of objects providing information ++ on global BGP state." ++ ::= { bgpMIBGroups 1 } ++ ++ bgp4MIBPeerGroup OBJECT-GROUP ++ OBJECTS { bgpPeerIdentifier, ++ bgpPeerState, ++ bgpPeerAdminStatus, ++ bgpPeerNegotiatedVersion, ++ bgpPeerLocalAddr, ++ bgpPeerLocalPort, ++ bgpPeerRemoteAddr, ++ bgpPeerRemotePort, ++ bgpPeerRemoteAs, ++ bgpPeerInUpdates, ++ bgpPeerOutUpdates, ++ bgpPeerInTotalMessages, ++ bgpPeerOutTotalMessages, ++ bgpPeerLastError, ++ bgpPeerFsmEstablishedTransitions, ++ bgpPeerFsmEstablishedTime, ++ bgpPeerConnectRetryInterval, ++ bgpPeerHoldTime, ++ bgpPeerKeepAlive, ++ bgpPeerHoldTimeConfigured, ++ bgpPeerKeepAliveConfigured, ++ bgpPeerMinASOriginationInterval, ++ bgpPeerMinRouteAdvertisementInterval, ++ bgpPeerInUpdateElapsedTime } ++ STATUS current ++ DESCRIPTION ++ "A collection of objects for managing ++ BGP peers." ++ ::= { bgpMIBGroups 2 } ++ ++ bgp4MIBRcvdPathAttrGroup OBJECT-GROUP ++ OBJECTS { bgpPathAttrPeer, ++ bgpPathAttrDestNetwork, ++ bgpPathAttrOrigin, ++ bgpPathAttrASPath, ++ bgpPathAttrNextHop, ++ bgpPathAttrInterASMetric } ++ STATUS obsolete ++ DESCRIPTION ++ "A collection of objects for managing BGP ++ path entries. ++ ++ This conformance group is obsolete, ++ replaced by bgp4MIBPathAttrGroup." ++ ::= { bgpMIBGroups 3 } ++ ++ bgp4MIBPathAttrGroup OBJECT-GROUP ++ OBJECTS { bgp4PathAttrPeer, ++ bgp4PathAttrIpAddrPrefixLen, ++ bgp4PathAttrIpAddrPrefix, ++ bgp4PathAttrOrigin, ++ bgp4PathAttrASPathSegment, ++ bgp4PathAttrNextHop, ++ bgp4PathAttrMultiExitDisc, ++ bgp4PathAttrLocalPref, ++ bgp4PathAttrAtomicAggregate, ++ bgp4PathAttrAggregatorAS, ++ bgp4PathAttrAggregatorAddr, ++ bgp4PathAttrCalcLocalPref, ++ bgp4PathAttrBest, ++ bgp4PathAttrUnknown } ++ STATUS current ++ DESCRIPTION ++ "A collection of objects for managing ++ BGP path entries." ++ ::= { bgpMIBGroups 4 } ++ ++ bgp4MIBNotificationGroup NOTIFICATION-GROUP ++ NOTIFICATIONS { bgpEstablished, ++ bgpBackwardTransition } ++ STATUS current ++ DESCRIPTION ++ "A collection of notifications for signaling ++ changes in BGP peer relationships." ++ ::= { bgpMIBGroups 5 } ++ ++ END +--- /dev/null ++++ b/mibs/GNOME-SMI.txt +@@ -0,0 +1,88 @@ ++GNOME-SMI DEFINITIONS ::= BEGIN ++ ++IMPORTS ++ MODULE-IDENTITY, ++ OBJECT-IDENTITY, ++ enterprises ++ FROM SNMPv2-SMI; ++ ++gnome MODULE-IDENTITY ++ LAST-UPDATED "200709070000Z" ++ ORGANIZATION "GNOME project" ++ CONTACT-INFO ++ "GNU Network Object Model Environment project ++ ++ see http://www.gnome.org for contact persons of a particular ++ area or subproject of GNOME. ++ ++ Administrative contact for MIB module: ++ ++ Jochen Friedrich ++ Ramsaystr. 9 ++ 63450 Hanau ++ Germany ++ ++ email: jochen@scram.de" ++ DESCRIPTION ++ "The Structure of GNOME." ++ ++ -- revision history ++ ++ REVISION "200709070000Z" -- Sep 07, 2007 ++ DESCRIPTION ++ "Fixed wrong enterprise number (how comes this ++ typo was unnoticed for so long?)." ++ ++ REVISION "200505070000Z" -- May 07, 2005 ++ DESCRIPTION ++ "Added gnomeLDAP subtree for LDAP definitions." ++ ++ REVISION "200312070000Z" -- December 07, 2003 ++ DESCRIPTION ++ "Added gnomeSysadmin subtree for GNOME project system administration. ++ Updated contact info." ++ ++ REVISION "9809010000Z" -- September 01, 1998 ++ DESCRIPTION ++ "Initial version." ++ ++ ::= { enterprises 3319 } -- assigned by IANA ++ ++gnomeProducts OBJECT-IDENTITY ++ STATUS current ++ DESCRIPTION ++ "gnomeProducts is the root OBJECT IDENTIFIER from ++ which sysObjectID values are assigned." ++ ::= { gnome 1 } ++ ++gnomeMgmt OBJECT-IDENTITY ++ STATUS current ++ DESCRIPTION ++ "gnomeMgmt defines the subtree for production GNOME related ++ MIB registrations." ++ ::= { gnome 2 } ++ ++gnomeTest OBJECT-IDENTITY ++ STATUS current ++ DESCRIPTION ++ "gnomeTest defines the subtree for testing GNOME related ++ MIB registrations." ++ ::= { gnome 3 } ++ ++gnomeSysadmin OBJECT-IDENTITY ++ STATUS current ++ DESCRIPTION ++ "gnomeSysadmin defines the subtree for GNOME related Sysadmin ++ MIB registrations." ++ ::= { gnome 4 } ++ ++gnomeLDAP OBJECT-IDENTITY ++ STATUS current ++ DESCRIPTION ++ "gnomeLDAP defines the subtree for GNOME related LDAP ++ registrations." ++ ::= { gnome 5 } ++ ++-- more to come if necessary. ++ ++END +--- /dev/null ++++ b/mibs/OSPF-MIB.txt +@@ -0,0 +1,2723 @@ ++OSPF-MIB DEFINITIONS ::= BEGIN ++ ++ IMPORTS ++ MODULE-IDENTITY, OBJECT-TYPE, Counter32, Gauge32, ++ Integer32, IpAddress ++ FROM SNMPv2-SMI ++ TEXTUAL-CONVENTION, TruthValue, RowStatus ++ FROM SNMPv2-TC ++ MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF ++ mib-2 FROM RFC1213-MIB; ++ ++-- This MIB module uses the extended OBJECT-TYPE macro as ++-- defined in [9]. ++ ++ospf MODULE-IDENTITY ++ LAST-UPDATED "9501201225Z" -- Fri Jan 20 12:25:50 PST 1995 ++ ORGANIZATION "IETF OSPF Working Group" ++ CONTACT-INFO ++ " Fred Baker ++ Postal: Cisco Systems ++ 519 Lado Drive ++ Santa Barbara, California 93111 ++ Tel: +1 805 681 0115 ++ E-Mail: fred@cisco.com ++ ++ Rob Coltun ++ Postal: RainbowBridge Communications ++ Tel: (301) 340-9416 ++ E-Mail: rcoltun@rainbow-bridge.com" ++ DESCRIPTION ++ "The MIB module to describe the OSPF Version 2 ++ Protocol" ++ ::= { mib-2 14 } ++ ++-- The Area ID, in OSPF, has the same format as an IP Address, ++-- but has the function of defining a summarization point for ++-- Link State Advertisements ++ ++AreaID ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "An OSPF Area Identifier." ++ SYNTAX IpAddress ++ ++ ++-- The Router ID, in OSPF, has the same format as an IP Address, ++-- but identifies the router independent of its IP Address. ++ ++RouterID ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "A OSPF Router Identifier." ++ SYNTAX IpAddress ++ ++ ++-- The OSPF Metric is defined as an unsigned value in the range ++ ++Metric ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "The OSPF Internal Metric." ++ SYNTAX Integer32 (0..'FFFF'h) ++ ++BigMetric ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "The OSPF External Metric." ++ SYNTAX Integer32 (0..'FFFFFF'h) ++ ++-- Status Values ++ ++Status ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "The status of an interface: 'enabled' indicates that ++ it is willing to communicate with other OSPF Routers, ++ while 'disabled' indicates that it is not." ++ SYNTAX INTEGER { enabled (1), disabled (2) } ++ ++-- Time Durations measured in seconds ++ ++PositiveInteger ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "A positive integer. Values in excess are precluded as ++ unnecessary and prone to interoperability issues." ++ SYNTAX Integer32 (0..'7FFFFFFF'h) ++ ++HelloRange ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "The range of intervals on which hello messages are ++ exchanged." ++ SYNTAX Integer32 (1..'FFFF'h) ++ ++UpToMaxAge ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "The values that one might find or configure for ++ variables bounded by the maximum age of an LSA." ++ SYNTAX Integer32 (0..3600) ++ ++ ++-- The range of ifIndex ++ ++InterfaceIndex ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "The range of ifIndex." ++ SYNTAX Integer32 ++ ++ ++-- Potential Priorities for the Designated Router Election ++ ++DesignatedRouterPriority ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "The values defined for the priority of a system for ++ becoming the designated router." ++ SYNTAX Integer32 (0..'FF'h) ++ ++TOSType ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "Type of Service is defined as a mapping to the IP Type of ++ Service Flags as defined in the IP Forwarding Table MIB ++ ++ +-----+-----+-----+-----+-----+-----+-----+-----+ ++ | | | | ++ | PRECEDENCE | TYPE OF SERVICE | 0 | ++ | | | | ++ +-----+-----+-----+-----+-----+-----+-----+-----+ ++ ++ IP TOS IP TOS ++ Field Policy Field Policy ++ ++ Contents Code Contents Code ++ 0 0 0 0 ==> 0 0 0 0 1 ==> 2 ++ 0 0 1 0 ==> 4 0 0 1 1 ==> 6 ++ 0 1 0 0 ==> 8 0 1 0 1 ==> 10 ++ 0 1 1 0 ==> 12 0 1 1 1 ==> 14 ++ 1 0 0 0 ==> 16 1 0 0 1 ==> 18 ++ 1 0 1 0 ==> 20 1 0 1 1 ==> 22 ++ 1 1 0 0 ==> 24 1 1 0 1 ==> 26 ++ 1 1 1 0 ==> 28 1 1 1 1 ==> 30 ++ ++ The remaining values are left for future definition." ++ SYNTAX Integer32 (0..30) ++ ++ ++-- OSPF General Variables ++ ++-- These parameters apply globally to the Router's ++-- OSPF Process. ++ ++ospfGeneralGroup OBJECT IDENTIFIER ::= { ospf 1 } ++ ++ ++ ospfRouterId OBJECT-TYPE ++ SYNTAX RouterID ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "A 32-bit integer uniquely identifying the ++ router in the Autonomous System. ++ ++ By convention, to ensure uniqueness, this ++ should default to the value of one of the ++ router's IP interface addresses." ++ REFERENCE ++ "OSPF Version 2, C.1 Global parameters" ++ ::= { ospfGeneralGroup 1 } ++ ++ ++ ospfAdminStat OBJECT-TYPE ++ SYNTAX Status ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "The administrative status of OSPF in the ++ router. The value 'enabled' denotes that the ++ OSPF Process is active on at least one inter- ++ face; 'disabled' disables it on all inter- ++ faces." ++ ::= { ospfGeneralGroup 2 } ++ ++ ospfVersionNumber OBJECT-TYPE ++ SYNTAX INTEGER { version2 (2) } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The current version number of the OSPF proto- ++ col is 2." ++ REFERENCE ++ "OSPF Version 2, Title" ++ ::= { ospfGeneralGroup 3 } ++ ++ ++ ospfAreaBdrRtrStatus OBJECT-TYPE ++ SYNTAX TruthValue ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "A flag to note whether this router is an area ++ border router." ++ REFERENCE ++ "OSPF Version 2, Section 3 Splitting the AS into ++ Areas" ++ ::= { ospfGeneralGroup 4 } ++ ++ ++ ospfASBdrRtrStatus OBJECT-TYPE ++ SYNTAX TruthValue ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "A flag to note whether this router is config- ++ ured as an Autonomous System border router." ++ REFERENCE ++ "OSPF Version 2, Section 3.3 Classification of ++ routers" ++ ::= { ospfGeneralGroup 5 } ++ ++ ospfExternLsaCount OBJECT-TYPE ++ SYNTAX Gauge32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of external (LS type 5) link-state ++ advertisements in the link-state database." ++ REFERENCE ++ "OSPF Version 2, Appendix A.4.5 AS external link ++ advertisements" ++ ::= { ospfGeneralGroup 6 } ++ ++ ++ ospfExternLsaCksumSum OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The 32-bit unsigned sum of the LS checksums of ++ the external link-state advertisements con- ++ tained in the link-state database. This sum ++ can be used to determine if there has been a ++ change in a router's link state database, and ++ to compare the link-state database of two ++ routers." ++ ::= { ospfGeneralGroup 7 } ++ ++ ++ ospfTOSSupport OBJECT-TYPE ++ SYNTAX TruthValue ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "The router's support for type-of-service rout- ++ ing." ++ REFERENCE ++ "OSPF Version 2, Appendix F.1.2 Optional TOS ++ support" ++ ::= { ospfGeneralGroup 8 } ++ ++ ospfOriginateNewLsas OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of new link-state advertisements ++ that have been originated. This number is in- ++ cremented each time the router originates a new ++ LSA." ++ ::= { ospfGeneralGroup 9 } ++ ++ ++ ospfRxNewLsas OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of link-state advertisements re- ++ ceived determined to be new instantiations. ++ This number does not include newer instantia- ++ tions of self-originated link-state advertise- ++ ments." ++ ::= { ospfGeneralGroup 10 } ++ ++ ospfExtLsdbLimit OBJECT-TYPE ++ SYNTAX Integer32 (-1..'7FFFFFFF'h) ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "The maximum number of non-default AS- ++ external-LSAs entries that can be stored in the ++ link-state database. If the value is -1, then ++ there is no limit. ++ ++ When the number of non-default AS-external-LSAs ++ in a router's link-state database reaches ++ ospfExtLsdbLimit, the router enters Overflow- ++ State. The router never holds more than ++ ospfExtLsdbLimit non-default AS-external-LSAs ++ in its database. OspfExtLsdbLimit MUST be set ++ identically in all routers attached to the OSPF ++ backbone and/or any regular OSPF area. (i.e., ++ OSPF stub areas and NSSAs are excluded)." ++ DEFVAL { -1 } ++ ::= { ospfGeneralGroup 11 } ++ ++ ospfMulticastExtensions OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "A Bit Mask indicating whether the router is ++ forwarding IP multicast (Class D) datagrams ++ based on the algorithms defined in the Multi- ++ cast Extensions to OSPF. ++ ++ Bit 0, if set, indicates that the router can ++ forward IP multicast datagrams in the router's ++ directly attached areas (called intra-area mul- ++ ticast routing). ++ ++ Bit 1, if set, indicates that the router can ++ forward IP multicast datagrams between OSPF ++ areas (called inter-area multicast routing). ++ ++ Bit 2, if set, indicates that the router can ++ forward IP multicast datagrams between Auto- ++ nomous Systems (called inter-AS multicast rout- ++ ing). ++ ++ Only certain combinations of bit settings are ++ allowed, namely: 0 (no multicast forwarding is ++ enabled), 1 (intra-area multicasting only), 3 ++ (intra-area and inter-area multicasting), 5 ++ (intra-area and inter-AS multicasting) and 7 ++ (multicasting everywhere). By default, no mul- ++ ticast forwarding is enabled." ++ DEFVAL { 0 } ++ ::= { ospfGeneralGroup 12 } ++ ++ ospfExitOverflowInterval OBJECT-TYPE ++ SYNTAX PositiveInteger ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "The number of seconds that, after entering ++ OverflowState, a router will attempt to leave ++ OverflowState. This allows the router to again ++ originate non-default AS-external-LSAs. When ++ set to 0, the router will not leave Overflow- ++ State until restarted." ++ DEFVAL { 0 } ++ ::= { ospfGeneralGroup 13 } ++ ++ ++ ospfDemandExtensions OBJECT-TYPE ++ SYNTAX TruthValue ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "The router's support for demand routing." ++ REFERENCE ++ "OSPF Version 2, Appendix on Demand Routing" ++ ::= { ospfGeneralGroup 14 } ++ ++ ++-- The OSPF Area Data Structure contains information ++-- regarding the various areas. The interfaces and ++-- virtual links are configured as part of these areas. ++-- Area 0.0.0.0, by definition, is the Backbone Area ++ ++ ++ ospfAreaTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfAreaEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "Information describing the configured parame- ++ ters and cumulative statistics of the router's ++ attached areas." ++ REFERENCE ++ "OSPF Version 2, Section 6 The Area Data Struc- ++ ture" ++ ::= { ospf 2 } ++ ++ ++ ospfAreaEntry OBJECT-TYPE ++ SYNTAX OspfAreaEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "Information describing the configured parame- ++ ters and cumulative statistics of one of the ++ router's attached areas." ++ INDEX { ospfAreaId } ++ ::= { ospfAreaTable 1 } ++ ++OspfAreaEntry ::= ++ SEQUENCE { ++ ospfAreaId ++ AreaID, ++ ospfAuthType ++ Integer32, ++ ospfImportAsExtern ++ INTEGER, ++ ospfSpfRuns ++ Counter32, ++ ospfAreaBdrRtrCount ++ Gauge32, ++ ospfAsBdrRtrCount ++ Gauge32, ++ ospfAreaLsaCount ++ Gauge32, ++ ospfAreaLsaCksumSum ++ Integer32, ++ ospfAreaSummary ++ INTEGER, ++ ospfAreaStatus ++ RowStatus ++ } ++ ++ ospfAreaId OBJECT-TYPE ++ SYNTAX AreaID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "A 32-bit integer uniquely identifying an area. ++ Area ID 0.0.0.0 is used for the OSPF backbone." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospfAreaEntry 1 } ++ ++ ++ ospfAuthType OBJECT-TYPE ++ SYNTAX Integer32 ++ -- none (0), ++ -- simplePassword (1) ++ -- md5 (2) ++ -- reserved for specification by IANA (> 2) ++ MAX-ACCESS read-create ++ STATUS obsolete ++ DESCRIPTION ++ "The authentication type specified for an area. ++ Additional authentication types may be assigned ++ locally on a per Area basis." ++ REFERENCE ++ "OSPF Version 2, Appendix E Authentication" ++ DEFVAL { 0 } -- no authentication, by default ++ ::= { ospfAreaEntry 2 } ++ ++ ospfImportAsExtern OBJECT-TYPE ++ SYNTAX INTEGER { ++ importExternal (1), ++ importNoExternal (2), ++ importNssa (3) ++ } ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The area's support for importing AS external ++ link- state advertisements." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ DEFVAL { importExternal } ++ ::= { ospfAreaEntry 3 } ++ ++ ++ ospfSpfRuns OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of times that the intra-area route ++ table has been calculated using this area's ++ link-state database. This is typically done ++ using Dijkstra's algorithm." ++ ::= { ospfAreaEntry 4 } ++ ++ ++ ospfAreaBdrRtrCount OBJECT-TYPE ++ SYNTAX Gauge32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The total number of area border routers reach- ++ able within this area. This is initially zero, ++ and is calculated in each SPF Pass." ++ ::= { ospfAreaEntry 5 } ++ ++ ospfAsBdrRtrCount OBJECT-TYPE ++ SYNTAX Gauge32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The total number of Autonomous System border ++ routers reachable within this area. This is ++ initially zero, and is calculated in each SPF ++ Pass." ++ ::= { ospfAreaEntry 6 } ++ ++ ++ ospfAreaLsaCount OBJECT-TYPE ++ SYNTAX Gauge32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The total number of link-state advertisements ++ in this area's link-state database, excluding ++ AS External LSA's." ++ ::= { ospfAreaEntry 7 } ++ ++ ++ ospfAreaLsaCksumSum OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The 32-bit unsigned sum of the link-state ad- ++ vertisements' LS checksums contained in this ++ area's link-state database. This sum excludes ++ external (LS type 5) link-state advertisements. ++ The sum can be used to determine if there has ++ been a change in a router's link state data- ++ base, and to compare the link-state database of ++ two routers." ++ DEFVAL { 0 } ++ ::= { ospfAreaEntry 8 } ++ ++ ospfAreaSummary OBJECT-TYPE ++ SYNTAX INTEGER { ++ noAreaSummary (1), ++ sendAreaSummary (2) ++ } ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The variable ospfAreaSummary controls the im- ++ port of summary LSAs into stub areas. It has ++ no effect on other areas. ++ ++ If it is noAreaSummary, the router will neither ++ originate nor propagate summary LSAs into the ++ stub area. It will rely entirely on its de- ++ fault route. ++ ++ If it is sendAreaSummary, the router will both ++ summarize and propagate summary LSAs." ++ DEFVAL { noAreaSummary } ++ ::= { ospfAreaEntry 9 } ++ ++ ++ ospfAreaStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This variable displays the status of the en- ++ try. Setting it to 'invalid' has the effect of ++ rendering it inoperative. The internal effect ++ (row removal) is implementation dependent." ++ ::= { ospfAreaEntry 10 } ++ ++ ++-- OSPF Area Default Metric Table ++ ++-- The OSPF Area Default Metric Table describes the metrics ++-- that a default Area Border Router will advertise into a ++-- Stub area. ++ ++ ++ ospfStubAreaTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfStubAreaEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "The set of metrics that will be advertised by ++ a default Area Border Router into a stub area." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2, Area Parameters" ++ ::= { ospf 3 } ++ ++ ++ ospfStubAreaEntry OBJECT-TYPE ++ SYNTAX OspfStubAreaEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "The metric for a given Type of Service that ++ will be advertised by a default Area Border ++ Router into a stub area." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2, Area Parameters" ++ INDEX { ospfStubAreaId, ospfStubTOS } ++ ::= { ospfStubAreaTable 1 } ++ ++OspfStubAreaEntry ::= ++ SEQUENCE { ++ ospfStubAreaId ++ AreaID, ++ ospfStubTOS ++ TOSType, ++ ospfStubMetric ++ BigMetric, ++ ospfStubStatus ++ RowStatus, ++ ospfStubMetricType ++ INTEGER ++ } ++ ++ ospfStubAreaId OBJECT-TYPE ++ SYNTAX AreaID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The 32 bit identifier for the Stub Area. On ++ creation, this can be derived from the in- ++ stance." ++ ::= { ospfStubAreaEntry 1 } ++ ++ ++ ospfStubTOS OBJECT-TYPE ++ SYNTAX TOSType ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The Type of Service associated with the ++ metric. On creation, this can be derived from ++ the instance." ++ ::= { ospfStubAreaEntry 2 } ++ ++ ++ ospfStubMetric OBJECT-TYPE ++ SYNTAX BigMetric ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The metric value applied at the indicated type ++ of service. By default, this equals the least ++ metric at the type of service among the inter- ++ faces to other areas." ++ ::= { ospfStubAreaEntry 3 } ++ ++ ++ ospfStubStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This variable displays the status of the en- ++ try. Setting it to 'invalid' has the effect of ++ rendering it inoperative. The internal effect ++ (row removal) is implementation dependent." ++ ::= { ospfStubAreaEntry 4 } ++ ++ ospfStubMetricType OBJECT-TYPE ++ SYNTAX INTEGER { ++ ospfMetric (1), -- OSPF Metric ++ comparableCost (2), -- external type 1 ++ nonComparable (3) -- external type 2 ++ } ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This variable displays the type of metric ad- ++ vertised as a default route." ++ DEFVAL { ospfMetric } ++ ::= { ospfStubAreaEntry 5 } ++ ++-- OSPF Link State Database ++ ++-- The Link State Database contains the Link State ++-- Advertisements from throughout the areas that the ++-- device is attached to. ++ ++ ++ ospfLsdbTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfLsdbEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "The OSPF Process's Link State Database." ++ REFERENCE ++ "OSPF Version 2, Section 12 Link State Adver- ++ tisements" ++ ::= { ospf 4 } ++ ++ ++ ospfLsdbEntry OBJECT-TYPE ++ SYNTAX OspfLsdbEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A single Link State Advertisement." ++ INDEX { ospfLsdbAreaId, ospfLsdbType, ++ ospfLsdbLsid, ospfLsdbRouterId } ++ ::= { ospfLsdbTable 1 } ++ ++OspfLsdbEntry ::= ++ SEQUENCE { ++ ospfLsdbAreaId ++ AreaID, ++ ospfLsdbType ++ INTEGER, ++ ospfLsdbLsid ++ IpAddress, ++ ospfLsdbRouterId ++ RouterID, ++ ospfLsdbSequence ++ Integer32, ++ ospfLsdbAge ++ Integer32, ++ ospfLsdbChecksum ++ Integer32, ++ ospfLsdbAdvertisement ++ OCTET STRING ++ } ++ ospfLsdbAreaId OBJECT-TYPE ++ SYNTAX AreaID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The 32 bit identifier of the Area from which ++ the LSA was received." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospfLsdbEntry 1 } ++ ++-- External Link State Advertisements are permitted ++-- for backward compatibility, but should be displayed in ++-- the ospfExtLsdbTable rather than here. ++ ++ ospfLsdbType OBJECT-TYPE ++ SYNTAX INTEGER { ++ routerLink (1), ++ networkLink (2), ++ summaryLink (3), ++ asSummaryLink (4), ++ asExternalLink (5), -- but see ospfExtLsdbTable ++ multicastLink (6), ++ nssaExternalLink (7) ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The type of the link state advertisement. ++ Each link state type has a separate advertise- ++ ment format." ++ REFERENCE ++ "OSPF Version 2, Appendix A.4.1 The Link State ++ Advertisement header" ++ ::= { ospfLsdbEntry 2 } ++ ++ ospfLsdbLsid OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The Link State ID is an LS Type Specific field ++ containing either a Router ID or an IP Address; ++ it identifies the piece of the routing domain ++ that is being described by the advertisement." ++ REFERENCE ++ "OSPF Version 2, Section 12.1.4 Link State ID" ++ ::= { ospfLsdbEntry 3 } ++ ospfLsdbRouterId OBJECT-TYPE ++ SYNTAX RouterID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The 32 bit number that uniquely identifies the ++ originating router in the Autonomous System." ++ REFERENCE ++ "OSPF Version 2, Appendix C.1 Global parameters" ++ ::= { ospfLsdbEntry 4 } ++ ++-- Note that the OSPF Sequence Number is a 32 bit signed ++-- integer. It starts with the value '80000001'h, ++-- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h ++-- Thus, a typical sequence number will be very negative. ++ ++ ospfLsdbSequence OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The sequence number field is a signed 32-bit ++ integer. It is used to detect old and dupli- ++ cate link state advertisements. The space of ++ sequence numbers is linearly ordered. The ++ larger the sequence number the more recent the ++ advertisement." ++ REFERENCE ++ "OSPF Version 2, Section 12.1.6 LS sequence ++ number" ++ ::= { ospfLsdbEntry 5 } ++ ++ ++ ospfLsdbAge OBJECT-TYPE ++ SYNTAX Integer32 -- Should be 0..MaxAge ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "This field is the age of the link state adver- ++ tisement in seconds." ++ REFERENCE ++ "OSPF Version 2, Section 12.1.1 LS age" ++ ::= { ospfLsdbEntry 6 } ++ ++ ospfLsdbChecksum OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "This field is the checksum of the complete ++ contents of the advertisement, excepting the ++ age field. The age field is excepted so that ++ an advertisement's age can be incremented ++ without updating the checksum. The checksum ++ used is the same that is used for ISO connec- ++ tionless datagrams; it is commonly referred to ++ as the Fletcher checksum." ++ REFERENCE ++ "OSPF Version 2, Section 12.1.7 LS checksum" ++ ::= { ospfLsdbEntry 7 } ++ ++ ++ ospfLsdbAdvertisement OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE (1..65535)) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The entire Link State Advertisement, including ++ its header." ++ REFERENCE ++ "OSPF Version 2, Section 12 Link State Adver- ++ tisements" ++ ::= { ospfLsdbEntry 8 } ++ ++ ++-- Address Range Table ++ ++-- The Address Range Table acts as an adjunct to the Area ++-- Table; It describes those Address Range Summaries that ++-- are configured to be propagated from an Area to reduce ++-- the amount of information about it which is known beyond ++-- its borders. ++ ++ ospfAreaRangeTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfAreaRangeEntry ++ MAX-ACCESS not-accessible ++ STATUS obsolete ++ DESCRIPTION ++ "A range if IP addresses specified by an IP ++ address/IP network mask pair. For example, ++ class B address range of X.X.X.X with a network ++ mask of 255.255.0.0 includes all IP addresses ++ from X.X.0.0 to X.X.255.255" ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospf 5 } ++ ospfAreaRangeEntry OBJECT-TYPE ++ SYNTAX OspfAreaRangeEntry ++ MAX-ACCESS not-accessible ++ STATUS obsolete ++ DESCRIPTION ++ "A range if IP addresses specified by an IP ++ address/IP network mask pair. For example, ++ class B address range of X.X.X.X with a network ++ mask of 255.255.0.0 includes all IP addresses ++ from X.X.0.0 to X.X.255.255" ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ INDEX { ospfAreaRangeAreaId, ospfAreaRangeNet } ++ ::= { ospfAreaRangeTable 1 } ++ ++OspfAreaRangeEntry ::= ++ SEQUENCE { ++ ospfAreaRangeAreaId ++ AreaID, ++ ospfAreaRangeNet ++ IpAddress, ++ ospfAreaRangeMask ++ IpAddress, ++ ospfAreaRangeStatus ++ RowStatus, ++ ospfAreaRangeEffect ++ INTEGER ++ } ++ ++ ospfAreaRangeAreaId OBJECT-TYPE ++ SYNTAX AreaID ++ MAX-ACCESS read-only ++ STATUS obsolete ++ DESCRIPTION ++ "The Area the Address Range is to be found ++ within." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospfAreaRangeEntry 1 } ++ ++ ++ ospfAreaRangeNet OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS obsolete ++ DESCRIPTION ++ "The IP Address of the Net or Subnet indicated ++ by the range." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospfAreaRangeEntry 2 } ++ ++ ++ ospfAreaRangeMask OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-create ++ STATUS obsolete ++ DESCRIPTION ++ "The Subnet Mask that pertains to the Net or ++ Subnet." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospfAreaRangeEntry 3 } ++ ++ ospfAreaRangeStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS obsolete ++ DESCRIPTION ++ "This variable displays the status of the en- ++ try. Setting it to 'invalid' has the effect of ++ rendering it inoperative. The internal effect ++ (row removal) is implementation dependent." ++ ::= { ospfAreaRangeEntry 4 } ++ ++ ++ ospfAreaRangeEffect OBJECT-TYPE ++ SYNTAX INTEGER { ++ advertiseMatching (1), ++ doNotAdvertiseMatching (2) ++ } ++ MAX-ACCESS read-create ++ STATUS obsolete ++ DESCRIPTION ++ "Subnets subsumed by ranges either trigger the ++ advertisement of the indicated summary (adver- ++ tiseMatching), or result in the subnet's not ++ being advertised at all outside the area." ++ DEFVAL { advertiseMatching } ++ ::= { ospfAreaRangeEntry 5 } ++ ++ ++ ++-- OSPF Host Table ++ ++-- The Host/Metric Table indicates what hosts are directly ++-- attached to the Router, and what metrics and types of ++-- service should be advertised for them. ++ ++ ospfHostTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfHostEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "The list of Hosts, and their metrics, that the ++ router will advertise as host routes." ++ REFERENCE ++ "OSPF Version 2, Appendix C.6 Host route param- ++ eters" ++ ::= { ospf 6 } ++ ++ ++ ospfHostEntry OBJECT-TYPE ++ SYNTAX OspfHostEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A metric to be advertised, for a given type of ++ service, when a given host is reachable." ++ INDEX { ospfHostIpAddress, ospfHostTOS } ++ ::= { ospfHostTable 1 } ++ ++OspfHostEntry ::= ++ SEQUENCE { ++ ospfHostIpAddress ++ IpAddress, ++ ospfHostTOS ++ TOSType, ++ ospfHostMetric ++ Metric, ++ ospfHostStatus ++ RowStatus, ++ ospfHostAreaID ++ AreaID ++ } ++ ++ ospfHostIpAddress OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP Address of the Host." ++ REFERENCE ++ "OSPF Version 2, Appendix C.6 Host route parame- ++ ters" ++ ::= { ospfHostEntry 1 } ++ ++ ++ ospfHostTOS OBJECT-TYPE ++ SYNTAX TOSType ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The Type of Service of the route being config- ++ ured." ++ REFERENCE ++ "OSPF Version 2, Appendix C.6 Host route parame- ++ ters" ++ ::= { ospfHostEntry 2 } ++ ++ ++ ospfHostMetric OBJECT-TYPE ++ SYNTAX Metric ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The Metric to be advertised." ++ REFERENCE ++ "OSPF Version 2, Appendix C.6 Host route parame- ++ ters" ++ ::= { ospfHostEntry 3 } ++ ++ ospfHostStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This variable displays the status of the en- ++ try. Setting it to 'invalid' has the effect of ++ rendering it inoperative. The internal effect ++ (row removal) is implementation dependent." ++ ::= { ospfHostEntry 4 } ++ ++ ++ ospfHostAreaID OBJECT-TYPE ++ SYNTAX AreaID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The Area the Host Entry is to be found within. ++ By default, the area that a subsuming OSPF in- ++ terface is in, or 0.0.0.0" ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospfHostEntry 5 } ++ ++ ++-- OSPF Interface Table ++ ++-- The OSPF Interface Table augments the ipAddrTable ++-- with OSPF specific information. ++ ++ ospfIfTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfIfEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "The OSPF Interface Table describes the inter- ++ faces from the viewpoint of OSPF." ++ REFERENCE ++ "OSPF Version 2, Appendix C.3 Router interface ++ parameters" ++ ::= { ospf 7 } ++ ++ ++ ospfIfEntry OBJECT-TYPE ++ SYNTAX OspfIfEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "The OSPF Interface Entry describes one inter- ++ face from the viewpoint of OSPF." ++ INDEX { ospfIfIpAddress, ospfAddressLessIf } ++ ::= { ospfIfTable 1 } ++ ++OspfIfEntry ::= ++ SEQUENCE { ++ ospfIfIpAddress ++ IpAddress, ++ ospfAddressLessIf ++ Integer32, ++ ospfIfAreaId ++ AreaID, ++ ospfIfType ++ INTEGER, ++ ospfIfAdminStat ++ Status, ++ ospfIfRtrPriority ++ DesignatedRouterPriority, ++ ospfIfTransitDelay ++ UpToMaxAge, ++ ospfIfRetransInterval ++ UpToMaxAge, ++ ospfIfHelloInterval ++ HelloRange, ++ ospfIfRtrDeadInterval ++ PositiveInteger, ++ ospfIfPollInterval ++ PositiveInteger, ++ ospfIfState ++ INTEGER, ++ ospfIfDesignatedRouter ++ IpAddress, ++ ospfIfBackupDesignatedRouter ++ IpAddress, ++ ospfIfEvents ++ Counter32, ++ ospfIfAuthType ++ INTEGER, ++ ospfIfAuthKey ++ OCTET STRING, ++ ospfIfStatus ++ RowStatus, ++ ospfIfMulticastForwarding ++ INTEGER, ++ ospfIfDemand ++ TruthValue ++ } ++ ++ ospfIfIpAddress OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP address of this OSPF interface." ++ ::= { ospfIfEntry 1 } ++ ++ ospfAddressLessIf OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "For the purpose of easing the instancing of ++ addressed and addressless interfaces; This ++ variable takes the value 0 on interfaces with ++ IP Addresses, and the corresponding value of ++ ifIndex for interfaces having no IP Address." ++ ::= { ospfIfEntry 2 } ++ ospfIfAreaId OBJECT-TYPE ++ SYNTAX AreaID ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "A 32-bit integer uniquely identifying the area ++ to which the interface connects. Area ID ++ 0.0.0.0 is used for the OSPF backbone." ++ DEFVAL { '00000000'H } -- 0.0.0.0 ++ ::= { ospfIfEntry 3 } ++ ++ ospfIfType OBJECT-TYPE ++ SYNTAX INTEGER { ++ broadcast (1), ++ nbma (2), ++ pointToPoint (3), ++ pointToMultipoint (5) ++ } ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The OSPF interface type. ++ ++ By way of a default, this field may be intuited ++ from the corresponding value of ifType. Broad- ++ cast LANs, such as Ethernet and IEEE 802.5, ++ take the value 'broadcast', X.25 and similar ++ technologies take the value 'nbma', and links ++ that are definitively point to point take the ++ value 'pointToPoint'." ++ ::= { ospfIfEntry 4 } ++ ++ ++ ospfIfAdminStat OBJECT-TYPE ++ SYNTAX Status ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The OSPF interface's administrative status. ++ The value formed on the interface, and the in- ++ terface will be advertised as an internal route ++ to some area. The value 'disabled' denotes ++ that the interface is external to OSPF." ++ DEFVAL { enabled } ++ ::= { ospfIfEntry 5 } ++ ++ ospfIfRtrPriority OBJECT-TYPE ++ SYNTAX DesignatedRouterPriority ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The priority of this interface. Used in ++ multi-access networks, this field is used in ++ the designated router election algorithm. The ++ value 0 signifies that the router is not eligi- ++ ble to become the designated router on this ++ particular network. In the event of a tie in ++ this value, routers will use their Router ID as ++ a tie breaker." ++ DEFVAL { 1 } ++ ::= { ospfIfEntry 6 } ++ ++ ++ ospfIfTransitDelay OBJECT-TYPE ++ SYNTAX UpToMaxAge ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The estimated number of seconds it takes to ++ transmit a link state update packet over this ++ interface." ++ DEFVAL { 1 } ++ ::= { ospfIfEntry 7 } ++ ++ ++ ospfIfRetransInterval OBJECT-TYPE ++ SYNTAX UpToMaxAge ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The number of seconds between link-state ad- ++ vertisement retransmissions, for adjacencies ++ belonging to this interface. This value is ++ also used when retransmitting database descrip- ++ tion and link-state request packets." ++ DEFVAL { 5 } ++ ::= { ospfIfEntry 8 } ++ ++ ++ ospfIfHelloInterval OBJECT-TYPE ++ SYNTAX HelloRange ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The length of time, in seconds, between the ++ Hello packets that the router sends on the in- ++ terface. This value must be the same for all ++ routers attached to a common network." ++ DEFVAL { 10 } ++ ::= { ospfIfEntry 9 } ++ ++ ++ ospfIfRtrDeadInterval OBJECT-TYPE ++ SYNTAX PositiveInteger ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The number of seconds that a router's Hello ++ packets have not been seen before it's neigh- ++ bors declare the router down. This should be ++ some multiple of the Hello interval. This ++ value must be the same for all routers attached ++ to a common network." ++ DEFVAL { 40 } ++ ::= { ospfIfEntry 10 } ++ ++ ++ ospfIfPollInterval OBJECT-TYPE ++ SYNTAX PositiveInteger ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The larger time interval, in seconds, between ++ the Hello packets sent to an inactive non- ++ broadcast multi- access neighbor." ++ DEFVAL { 120 } ++ ::= { ospfIfEntry 11 } ++ ++ ++ ospfIfState OBJECT-TYPE ++ SYNTAX INTEGER { ++ down (1), ++ loopback (2), ++ waiting (3), ++ pointToPoint (4), ++ designatedRouter (5), ++ backupDesignatedRouter (6), ++ otherDesignatedRouter (7) ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The OSPF Interface State." ++ DEFVAL { down } ++ ::= { ospfIfEntry 12 } ++ ++ ++ ospfIfDesignatedRouter OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP Address of the Designated Router." ++ DEFVAL { '00000000'H } -- 0.0.0.0 ++ ::= { ospfIfEntry 13 } ++ ++ ++ ospfIfBackupDesignatedRouter OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP Address of the Backup Designated ++ Router." ++ DEFVAL { '00000000'H } -- 0.0.0.0 ++ ::= { ospfIfEntry 14 } ++ ++ ospfIfEvents OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of times this OSPF interface has ++ changed its state, or an error has occurred." ++ ::= { ospfIfEntry 15 } ++ ++ ++ ospfIfAuthKey OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE (0..256)) ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The Authentication Key. If the Area's Author- ++ ization Type is simplePassword, and the key ++ length is shorter than 8 octets, the agent will ++ left adjust and zero fill to 8 octets. ++ ++ Note that unauthenticated interfaces need no ++ authentication key, and simple password authen- ++ tication cannot use a key of more than 8 oc- ++ tets. Larger keys are useful only with authen- ++ tication mechanisms not specified in this docu- ++ ment. ++ ++ When read, ospfIfAuthKey always returns an Oc- ++ tet String of length zero." ++ REFERENCE ++ "OSPF Version 2, Section 9 The Interface Data ++ Structure" ++ DEFVAL { '0000000000000000'H } -- 0.0.0.0.0.0.0.0 ++ ::= { ospfIfEntry 16 } ++ ++ ospfIfStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This variable displays the status of the en- ++ try. Setting it to 'invalid' has the effect of ++ rendering it inoperative. The internal effect ++ (row removal) is implementation dependent." ++ ::= { ospfIfEntry 17 } ++ ++ ++ ospfIfMulticastForwarding OBJECT-TYPE ++ SYNTAX INTEGER { ++ blocked (1), -- no multicast forwarding ++ multicast (2), -- using multicast address ++ unicast (3) -- to each OSPF neighbor ++ } ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The way multicasts should forwarded on this ++ interface; not forwarded, forwarded as data ++ link multicasts, or forwarded as data link uni- ++ casts. Data link multicasting is not meaning- ++ ful on point to point and NBMA interfaces, and ++ setting ospfMulticastForwarding to 0 effective- ++ ly disables all multicast forwarding." ++ DEFVAL { blocked } ++ ::= { ospfIfEntry 18 } ++ ++ ++ ospfIfDemand OBJECT-TYPE ++ SYNTAX TruthValue ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "Indicates whether Demand OSPF procedures (hel- ++ lo supression to FULL neighbors and setting the ++ DoNotAge flag on proogated LSAs) should be per- ++ formed on this interface." ++ DEFVAL { false } ++ ::= { ospfIfEntry 19 } ++ ++ ++ ospfIfAuthType OBJECT-TYPE ++ SYNTAX INTEGER (0..255) ++ -- none (0), ++ -- simplePassword (1) ++ -- md5 (2) ++ -- reserved for specification by IANA (> 2) ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The authentication type specified for an in- ++ terface. Additional authentication types may ++ be assigned locally." ++ REFERENCE ++ "OSPF Version 2, Appendix E Authentication" ++ DEFVAL { 0 } -- no authentication, by default ++ ::= { ospfIfEntry 20 } ++ ++ ++-- OSPF Interface Metric Table ++ ++-- The Metric Table describes the metrics to be advertised ++-- for a specified interface at the various types of service. ++-- As such, this table is an adjunct of the OSPF Interface ++-- Table. ++ ++-- Types of service, as defined by RFC 791, have the ability ++-- to request low delay, high bandwidth, or reliable linkage. ++ ++-- For the purposes of this specification, the measure of ++-- bandwidth ++ ++-- Metric = 10^8 / ifSpeed ++ ++-- is the default value. For multiple link interfaces, note ++-- that ifSpeed is the sum of the individual link speeds. ++-- This yields a number having the following typical values: ++ ++-- Network Type/bit rate Metric ++ ++-- >= 100 MBPS 1 ++-- Ethernet/802.3 10 ++-- E1 48 ++-- T1 (ESF) 65 ++-- 64 KBPS 1562 ++-- 56 KBPS 1785 ++-- 19.2 KBPS 5208 ++-- 9.6 KBPS 10416 ++ ++-- Routes that are not specified use the default (TOS 0) metric ++ ++ ospfIfMetricTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfIfMetricEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "The TOS metrics for a non-virtual interface ++ identified by the interface index." ++ REFERENCE ++ "OSPF Version 2, Appendix C.3 Router interface ++ parameters" ++ ::= { ospf 8 } ++ ++ ospfIfMetricEntry OBJECT-TYPE ++ SYNTAX OspfIfMetricEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A particular TOS metric for a non-virtual in- ++ terface identified by the interface index." ++ REFERENCE ++ "OSPF Version 2, Appendix C.3 Router interface ++ parameters" ++ INDEX { ospfIfMetricIpAddress, ++ ospfIfMetricAddressLessIf, ++ ospfIfMetricTOS } ++ ::= { ospfIfMetricTable 1 } ++ ++OspfIfMetricEntry ::= ++ SEQUENCE { ++ ospfIfMetricIpAddress ++ IpAddress, ++ ospfIfMetricAddressLessIf ++ Integer32, ++ ospfIfMetricTOS ++ TOSType, ++ ospfIfMetricValue ++ Metric, ++ ospfIfMetricStatus ++ RowStatus ++ } ++ ++ ospfIfMetricIpAddress OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP address of this OSPF interface. On row ++ creation, this can be derived from the in- ++ stance." ++ ::= { ospfIfMetricEntry 1 } ++ ++ ospfIfMetricAddressLessIf OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "For the purpose of easing the instancing of ++ addressed and addressless interfaces; This ++ variable takes the value 0 on interfaces with ++ IP Addresses, and the value of ifIndex for in- ++ terfaces having no IP Address. On row crea- ++ tion, this can be derived from the instance." ++ ::= { ospfIfMetricEntry 2 } ++ ++ ++ ospfIfMetricTOS OBJECT-TYPE ++ SYNTAX TOSType ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The type of service metric being referenced. ++ On row creation, this can be derived from the ++ instance." ++ ::= { ospfIfMetricEntry 3 } ++ ++ ++ ospfIfMetricValue OBJECT-TYPE ++ SYNTAX Metric ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The metric of using this type of service on ++ this interface. The default value of the TOS 0 ++ Metric is 10^8 / ifSpeed." ++ ::= { ospfIfMetricEntry 4 } ++ ++ ospfIfMetricStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This variable displays the status of the en- ++ try. Setting it to 'invalid' has the effect of ++ rendering it inoperative. The internal effect ++ (row removal) is implementation dependent." ++ ::= { ospfIfMetricEntry 5 } ++ ++ ++-- OSPF Virtual Interface Table ++ ++-- The Virtual Interface Table describes the virtual ++-- links that the OSPF Process is configured to ++-- carry on. ++ ++ ospfVirtIfTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfVirtIfEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "Information about this router's virtual inter- ++ faces." ++ REFERENCE ++ "OSPF Version 2, Appendix C.4 Virtual link ++ parameters" ++ ::= { ospf 9 } ++ ++ ++ ospfVirtIfEntry OBJECT-TYPE ++ SYNTAX OspfVirtIfEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "Information about a single Virtual Interface." ++ INDEX { ospfVirtIfAreaId, ospfVirtIfNeighbor } ++ ::= { ospfVirtIfTable 1 } ++ ++OspfVirtIfEntry ::= ++ SEQUENCE { ++ ospfVirtIfAreaId ++ AreaID, ++ ospfVirtIfNeighbor ++ RouterID, ++ ospfVirtIfTransitDelay ++ UpToMaxAge, ++ ospfVirtIfRetransInterval ++ UpToMaxAge, ++ ospfVirtIfHelloInterval ++ HelloRange, ++ ospfVirtIfRtrDeadInterval ++ PositiveInteger, ++ ospfVirtIfState ++ INTEGER, ++ ospfVirtIfEvents ++ Counter32, ++ ospfVirtIfAuthType ++ INTEGER, ++ ospfVirtIfAuthKey ++ OCTET STRING, ++ ospfVirtIfStatus ++ RowStatus ++ } ++ ++ ospfVirtIfAreaId OBJECT-TYPE ++ SYNTAX AreaID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The Transit Area that the Virtual Link ++ traverses. By definition, this is not 0.0.0.0" ++ ::= { ospfVirtIfEntry 1 } ++ ++ ++ ospfVirtIfNeighbor OBJECT-TYPE ++ SYNTAX RouterID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The Router ID of the Virtual Neighbor." ++ ::= { ospfVirtIfEntry 2 } ++ ++ ++ ospfVirtIfTransitDelay OBJECT-TYPE ++ SYNTAX UpToMaxAge ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The estimated number of seconds it takes to ++ transmit a link- state update packet over this ++ interface." ++ DEFVAL { 1 } ++ ::= { ospfVirtIfEntry 3 } ++ ++ ++ ospfVirtIfRetransInterval OBJECT-TYPE ++ SYNTAX UpToMaxAge ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The number of seconds between link-state ad- ++ vertisement retransmissions, for adjacencies ++ belonging to this interface. This value is ++ also used when retransmitting database descrip- ++ tion and link-state request packets. This ++ value should be well over the expected round- ++ trip time." ++ DEFVAL { 5 } ++ ::= { ospfVirtIfEntry 4 } ++ ++ ++ ospfVirtIfHelloInterval OBJECT-TYPE ++ SYNTAX HelloRange ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The length of time, in seconds, between the ++ Hello packets that the router sends on the in- ++ terface. This value must be the same for the ++ virtual neighbor." ++ DEFVAL { 10 } ++ ::= { ospfVirtIfEntry 5 } ++ ++ ++ ospfVirtIfRtrDeadInterval OBJECT-TYPE ++ SYNTAX PositiveInteger ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The number of seconds that a router's Hello ++ packets have not been seen before it's neigh- ++ bors declare the router down. This should be ++ some multiple of the Hello interval. This ++ value must be the same for the virtual neigh- ++ bor." ++ DEFVAL { 60 } ++ ::= { ospfVirtIfEntry 6 } ++ ++ ++ ospfVirtIfState OBJECT-TYPE ++ SYNTAX INTEGER { ++ down (1), -- these use the same encoding ++ pointToPoint (4) -- as the ospfIfTable ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "OSPF virtual interface states." ++ DEFVAL { down } ++ ::= { ospfVirtIfEntry 7 } ++ ++ ++ ospfVirtIfEvents OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of state changes or error events on ++ this Virtual Link" ++ ::= { ospfVirtIfEntry 8 } ++ ++ ++ ospfVirtIfAuthKey OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE(0..256)) ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "If Authentication Type is simplePassword, the ++ device will left adjust and zero fill to 8 oc- ++ tets. ++ ++ Note that unauthenticated interfaces need no ++ authentication key, and simple password authen- ++ tication cannot use a key of more than 8 oc- ++ tets. Larger keys are useful only with authen- ++ tication mechanisms not specified in this docu- ++ ment. ++ ++ When read, ospfVifAuthKey always returns a ++ string of length zero." ++ REFERENCE ++ "OSPF Version 2, Section 9 The Interface Data ++ Structure" ++ DEFVAL { '0000000000000000'H } -- 0.0.0.0.0.0.0.0 ++ ::= { ospfVirtIfEntry 9 } ++ ++ ++ ospfVirtIfStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This variable displays the status of the en- ++ try. Setting it to 'invalid' has the effect of ++ rendering it inoperative. The internal effect ++ (row removal) is implementation dependent." ++ ::= { ospfVirtIfEntry 10 } ++ ++ ++ ospfVirtIfAuthType OBJECT-TYPE ++ SYNTAX INTEGER (0..255) ++ -- none (0), ++ -- simplePassword (1) ++ -- md5 (2) ++ -- reserved for specification by IANA (> 2) ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The authentication type specified for a virtu- ++ al interface. Additional authentication types ++ may be assigned locally." ++ REFERENCE ++ "OSPF Version 2, Appendix E Authentication" ++ DEFVAL { 0 } -- no authentication, by default ++ ::= { ospfVirtIfEntry 11 } ++ ++ ++-- OSPF Neighbor Table ++ ++-- The OSPF Neighbor Table describes all neighbors in ++-- the locality of the subject router. ++ ++ ospfNbrTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfNbrEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A table of non-virtual neighbor information." ++ REFERENCE ++ "OSPF Version 2, Section 10 The Neighbor Data ++ Structure" ++ ::= { ospf 10 } ++ ++ ++ ospfNbrEntry OBJECT-TYPE ++ SYNTAX OspfNbrEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "The information regarding a single neighbor." ++ REFERENCE ++ "OSPF Version 2, Section 10 The Neighbor Data ++ Structure" ++ INDEX { ospfNbrIpAddr, ospfNbrAddressLessIndex } ++ ::= { ospfNbrTable 1 } ++ ++OspfNbrEntry ::= ++ SEQUENCE { ++ ospfNbrIpAddr ++ IpAddress, ++ ospfNbrAddressLessIndex ++ InterfaceIndex, ++ ospfNbrRtrId ++ RouterID, ++ ospfNbrOptions ++ Integer32, ++ ospfNbrPriority ++ DesignatedRouterPriority, ++ ospfNbrState ++ INTEGER, ++ ospfNbrEvents ++ Counter32, ++ ospfNbrLsRetransQLen ++ Gauge32, ++ ospfNbmaNbrStatus ++ RowStatus, ++ ospfNbmaNbrPermanence ++ INTEGER, ++ ospfNbrHelloSuppressed ++ TruthValue ++ } ++ ++ ospfNbrIpAddr OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP address this neighbor is using in its ++ IP Source Address. Note that, on addressless ++ links, this will not be 0.0.0.0, but the ad- ++ dress of another of the neighbor's interfaces." ++ ::= { ospfNbrEntry 1 } ++ ++ ++ ospfNbrAddressLessIndex OBJECT-TYPE ++ SYNTAX InterfaceIndex ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "On an interface having an IP Address, zero. ++ On addressless interfaces, the corresponding ++ value of ifIndex in the Internet Standard MIB. ++ On row creation, this can be derived from the ++ instance." ++ ::= { ospfNbrEntry 2 } ++ ++ ++ ospfNbrRtrId OBJECT-TYPE ++ SYNTAX RouterID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "A 32-bit integer (represented as a type IpAd- ++ dress) uniquely identifying the neighboring ++ router in the Autonomous System." ++ DEFVAL { '00000000'H } -- 0.0.0.0 ++ ::= { ospfNbrEntry 3 } ++ ++ ++ ospfNbrOptions OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "A Bit Mask corresponding to the neighbor's op- ++ tions field. ++ ++ Bit 0, if set, indicates that the system will ++ operate on Type of Service metrics other than ++ TOS 0. If zero, the neighbor will ignore all ++ metrics except the TOS 0 metric. ++ ++ Bit 1, if set, indicates that the associated ++ area accepts and operates on external informa- ++ tion; if zero, it is a stub area. ++ ++ Bit 2, if set, indicates that the system is ca- ++ pable of routing IP Multicast datagrams; i.e., ++ that it implements the Multicast Extensions to ++ OSPF. ++ ++ Bit 3, if set, indicates that the associated ++ area is an NSSA. These areas are capable of ++ carrying type 7 external advertisements, which ++ are translated into type 5 external advertise- ++ ments at NSSA borders." ++ REFERENCE ++ "OSPF Version 2, Section 12.1.2 Options" ++ DEFVAL { 0 } ++ ::= { ospfNbrEntry 4 } ++ ++ ++ ospfNbrPriority OBJECT-TYPE ++ SYNTAX DesignatedRouterPriority ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The priority of this neighbor in the designat- ++ ed router election algorithm. The value 0 sig- ++ nifies that the neighbor is not eligible to be- ++ come the designated router on this particular ++ network." ++ DEFVAL { 1 } ++ ::= { ospfNbrEntry 5 } ++ ++ ++ ospfNbrState OBJECT-TYPE ++ SYNTAX INTEGER { ++ down (1), ++ attempt (2), ++ init (3), ++ twoWay (4), ++ exchangeStart (5), ++ exchange (6), ++ loading (7), ++ full (8) ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The State of the relationship with this Neigh- ++ bor." ++ REFERENCE ++ "OSPF Version 2, Section 10.1 Neighbor States" ++ DEFVAL { down } ++ ::= { ospfNbrEntry 6 } ++ ++ ++ ospfNbrEvents OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of times this neighbor relationship ++ has changed state, or an error has occurred." ++ ::= { ospfNbrEntry 7 } ++ ++ ++ ospfNbrLsRetransQLen OBJECT-TYPE ++ SYNTAX Gauge32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The current length of the retransmission ++ queue." ++ ::= { ospfNbrEntry 8 } ++ ++ ++ ospfNbmaNbrStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This variable displays the status of the en- ++ try. Setting it to 'invalid' has the effect of ++ rendering it inoperative. The internal effect ++ (row removal) is implementation dependent." ++ ::= { ospfNbrEntry 9 } ++ ++ ++ ospfNbmaNbrPermanence OBJECT-TYPE ++ SYNTAX INTEGER { ++ dynamic (1), -- learned through protocol ++ permanent (2) -- configured address ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "This variable displays the status of the en- ++ try. 'dynamic' and 'permanent' refer to how ++ the neighbor became known." ++ DEFVAL { permanent } ++ ::= { ospfNbrEntry 10 } ++ ++ ++ ospfNbrHelloSuppressed OBJECT-TYPE ++ SYNTAX TruthValue ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "Indicates whether Hellos are being suppressed ++ to the neighbor" ++ ::= { ospfNbrEntry 11 } ++ ++ ++-- OSPF Virtual Neighbor Table ++ ++-- This table describes all virtual neighbors. ++-- Since Virtual Links are configured in the ++-- virtual interface table, this table is read-only. ++ ++ ospfVirtNbrTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfVirtNbrEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A table of virtual neighbor information." ++ REFERENCE ++ "OSPF Version 2, Section 15 Virtual Links" ++ ::= { ospf 11 } ++ ++ ++ ospfVirtNbrEntry OBJECT-TYPE ++ SYNTAX OspfVirtNbrEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "Virtual neighbor information." ++ INDEX { ospfVirtNbrArea, ospfVirtNbrRtrId } ++ ::= { ospfVirtNbrTable 1 } ++ ++OspfVirtNbrEntry ::= ++ SEQUENCE { ++ ospfVirtNbrArea ++ AreaID, ++ ospfVirtNbrRtrId ++ RouterID, ++ ospfVirtNbrIpAddr ++ IpAddress, ++ ospfVirtNbrOptions ++ Integer32, ++ ospfVirtNbrState ++ INTEGER, ++ ospfVirtNbrEvents ++ Counter32, ++ ospfVirtNbrLsRetransQLen ++ Gauge32, ++ ospfVirtNbrHelloSuppressed ++ TruthValue ++ } ++ ++ ospfVirtNbrArea OBJECT-TYPE ++ SYNTAX AreaID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The Transit Area Identifier." ++ ::= { ospfVirtNbrEntry 1 } ++ ++ ++ ospfVirtNbrRtrId OBJECT-TYPE ++ SYNTAX RouterID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "A 32-bit integer uniquely identifying the ++ neighboring router in the Autonomous System." ++ ::= { ospfVirtNbrEntry 2 } ++ ++ ++ ospfVirtNbrIpAddr OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP address this Virtual Neighbor is us- ++ ing." ++ ::= { ospfVirtNbrEntry 3 } ++ ++ ++ ospfVirtNbrOptions OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "A Bit Mask corresponding to the neighbor's op- ++ tions field. ++ ++ Bit 1, if set, indicates that the system will ++ operate on Type of Service metrics other than ++ TOS 0. If zero, the neighbor will ignore all ++ metrics except the TOS 0 metric. ++ ++ Bit 2, if set, indicates that the system is ++ Network Multicast capable; ie, that it imple- ++ ments OSPF Multicast Routing." ++ ::= { ospfVirtNbrEntry 4 } ++ ospfVirtNbrState OBJECT-TYPE ++ SYNTAX INTEGER { ++ down (1), ++ attempt (2), ++ init (3), ++ twoWay (4), ++ exchangeStart (5), ++ exchange (6), ++ loading (7), ++ full (8) ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The state of the Virtual Neighbor Relation- ++ ship." ++ ::= { ospfVirtNbrEntry 5 } ++ ++ ++ ospfVirtNbrEvents OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of times this virtual link has ++ changed its state, or an error has occurred." ++ ::= { ospfVirtNbrEntry 6 } ++ ++ ++ ospfVirtNbrLsRetransQLen OBJECT-TYPE ++ SYNTAX Gauge32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The current length of the retransmission ++ queue." ++ ::= { ospfVirtNbrEntry 7 } ++ ++ ++ ospfVirtNbrHelloSuppressed OBJECT-TYPE ++ SYNTAX TruthValue ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "Indicates whether Hellos are being suppressed ++ to the neighbor" ++ ::= { ospfVirtNbrEntry 8 } ++ ++-- OSPF Link State Database, External ++ ++-- The Link State Database contains the Link State ++-- Advertisements from throughout the areas that the ++-- device is attached to. ++ ++-- This table is identical to the OSPF LSDB Table in ++-- format, but contains only External Link State ++-- Advertisements. The purpose is to allow external ++-- LSAs to be displayed once for the router rather ++-- than once in each non-stub area. ++ ++ ospfExtLsdbTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfExtLsdbEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "The OSPF Process's Links State Database." ++ REFERENCE ++ "OSPF Version 2, Section 12 Link State Adver- ++ tisements" ++ ::= { ospf 12 } ++ ++ ++ ospfExtLsdbEntry OBJECT-TYPE ++ SYNTAX OspfExtLsdbEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A single Link State Advertisement." ++ INDEX { ospfExtLsdbType, ospfExtLsdbLsid, ospfExtLsdbRouterId } ++ ::= { ospfExtLsdbTable 1 } ++ ++OspfExtLsdbEntry ::= ++ SEQUENCE { ++ ospfExtLsdbType ++ INTEGER, ++ ospfExtLsdbLsid ++ IpAddress, ++ ospfExtLsdbRouterId ++ RouterID, ++ ospfExtLsdbSequence ++ Integer32, ++ ospfExtLsdbAge ++ Integer32, ++ ospfExtLsdbChecksum ++ Integer32, ++ ospfExtLsdbAdvertisement ++ OCTET STRING ++ } ++ ++ ospfExtLsdbType OBJECT-TYPE ++ SYNTAX INTEGER { ++ asExternalLink (5) ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The type of the link state advertisement. ++ Each link state type has a separate advertise- ++ ment format." ++ REFERENCE ++ "OSPF Version 2, Appendix A.4.1 The Link State ++ Advertisement header" ++ ::= { ospfExtLsdbEntry 1 } ++ ++ ++ ospfExtLsdbLsid OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The Link State ID is an LS Type Specific field ++ containing either a Router ID or an IP Address; ++ it identifies the piece of the routing domain ++ that is being described by the advertisement." ++ REFERENCE ++ "OSPF Version 2, Section 12.1.4 Link State ID" ++ ::= { ospfExtLsdbEntry 2 } ++ ++ ++ ospfExtLsdbRouterId OBJECT-TYPE ++ SYNTAX RouterID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The 32 bit number that uniquely identifies the ++ originating router in the Autonomous System." ++ REFERENCE ++ "OSPF Version 2, Appendix C.1 Global parameters" ++ ::= { ospfExtLsdbEntry 3 } ++ ++-- Note that the OSPF Sequence Number is a 32 bit signed ++-- integer. It starts with the value '80000001'h, ++-- or -'7FFFFFFF'h, and increments until '7FFFFFFF'h ++-- Thus, a typical sequence number will be very negative. ++ ospfExtLsdbSequence OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The sequence number field is a signed 32-bit ++ integer. It is used to detect old and dupli- ++ cate link state advertisements. The space of ++ sequence numbers is linearly ordered. The ++ larger the sequence number the more recent the ++ advertisement." ++ REFERENCE ++ "OSPF Version 2, Section 12.1.6 LS sequence ++ number" ++ ::= { ospfExtLsdbEntry 4 } ++ ++ ++ ospfExtLsdbAge OBJECT-TYPE ++ SYNTAX Integer32 -- Should be 0..MaxAge ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "This field is the age of the link state adver- ++ tisement in seconds." ++ REFERENCE ++ "OSPF Version 2, Section 12.1.1 LS age" ++ ::= { ospfExtLsdbEntry 5 } ++ ++ ++ ospfExtLsdbChecksum OBJECT-TYPE ++ SYNTAX Integer32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "This field is the checksum of the complete ++ contents of the advertisement, excepting the ++ age field. The age field is excepted so that ++ an advertisement's age can be incremented ++ without updating the checksum. The checksum ++ used is the same that is used for ISO connec- ++ tionless datagrams; it is commonly referred to ++ as the Fletcher checksum." ++ REFERENCE ++ "OSPF Version 2, Section 12.1.7 LS checksum" ++ ::= { ospfExtLsdbEntry 6 } ++ ++ ++ ospfExtLsdbAdvertisement OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE(36)) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The entire Link State Advertisement, including ++ its header." ++ REFERENCE ++ "OSPF Version 2, Section 12 Link State Adver- ++ tisements" ++ ::= { ospfExtLsdbEntry 7 } ++ ++ ++-- OSPF Use of the CIDR Route Table ++ ++ospfRouteGroup OBJECT IDENTIFIER ::= { ospf 13 } ++ ++-- The IP Forwarding Table defines a number of objects for use by ++-- the routing protocol to externalize its information. Most of ++-- the variables (ipForwardDest, ipForwardMask, ipForwardPolicy, ++-- ipForwardNextHop, ipForwardIfIndex, ipForwardType, ++-- ipForwardProto, ipForwardAge, and ipForwardNextHopAS) are ++-- defined there. ++ ++-- Those that leave some discretion are defined here. ++ ++-- ipCidrRouteProto is, of course, ospf (13). ++ ++-- ipCidrRouteAge is the time since the route was first calculated, ++-- as opposed to the time since the last SPF run. ++ ++-- ipCidrRouteInfo is an OBJECT IDENTIFIER for use by the routing ++-- protocol. The following values shall be found there depending ++-- on the way the route was calculated. ++ ++ospfIntraArea OBJECT IDENTIFIER ::= { ospfRouteGroup 1 } ++ospfInterArea OBJECT IDENTIFIER ::= { ospfRouteGroup 2 } ++ospfExternalType1 OBJECT IDENTIFIER ::= { ospfRouteGroup 3 } ++ospfExternalType2 OBJECT IDENTIFIER ::= { ospfRouteGroup 4 } ++ ++-- ipCidrRouteMetric1 is, by definition, the primary routing ++-- metric. Therefore, it should be the metric that route ++-- selection is based on. For intra-area and inter-area routes, ++-- it is an OSPF metric. For External Type 1 (comparable value) ++-- routes, it is an OSPF metric plus the External Metric. For ++-- external Type 2 (non-comparable value) routes, it is the ++-- external metric. ++ ++-- ipCidrRouteMetric2 is, by definition, a secondary routing ++-- metric. Therefore, it should be the metric that breaks a tie ++-- among routes having equal metric1 values and the same ++-- calculation rule. For intra-area, inter-area routes, and ++-- External Type 1 (comparable value) routes, it is unused. For ++-- external Type 2 (non-comparable value) routes, it is the metric ++-- to the AS border router. ++ ++-- ipCidrRouteMetric3, ipCidrRouteMetric4, and ipCidrRouteMetric5 are ++-- unused. ++ ++-- ++-- The OSPF Area Aggregate Table ++-- ++-- This table replaces the OSPF Area Summary Table, being an ++-- extension of that for CIDR routers. ++ ++ ospfAreaAggregateTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF OspfAreaAggregateEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A range of IP addresses specified by an IP ++ address/IP network mask pair. For example, ++ class B address range of X.X.X.X with a network ++ mask of 255.255.0.0 includes all IP addresses ++ from X.X.0.0 to X.X.255.255. Note that if ++ ranges are configured such that one range sub- ++ sumes another range (e.g., 10.0.0.0 mask ++ 255.0.0.0 and 10.1.0.0 mask 255.255.0.0), the ++ most specific match is the preferred one." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospf 14 } ++ ++ ++ ospfAreaAggregateEntry OBJECT-TYPE ++ SYNTAX OspfAreaAggregateEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A range of IP addresses specified by an IP ++ address/IP network mask pair. For example, ++ class B address range of X.X.X.X with a network ++ mask of 255.255.0.0 includes all IP addresses ++ from X.X.0.0 to X.X.255.255. Note that if ++ ranges are range configured such that one range ++ subsumes another range (e.g., 10.0.0.0 mask ++ 255.0.0.0 and 10.1.0.0 mask 255.255.0.0), the ++ most specific match is the preferred one." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ INDEX { ospfAreaAggregateAreaID, ospfAreaAggregateLsdbType, ++ ospfAreaAggregateNet, ospfAreaAggregateMask } ++ ::= { ospfAreaAggregateTable 1 } ++ ++ ++OspfAreaAggregateEntry ::= ++ SEQUENCE { ++ ospfAreaAggregateAreaID ++ AreaID, ++ ospfAreaAggregateLsdbType ++ INTEGER, ++ ospfAreaAggregateNet ++ IpAddress, ++ ospfAreaAggregateMask ++ IpAddress, ++ ospfAreaAggregateStatus ++ RowStatus, ++ ospfAreaAggregateEffect ++ INTEGER ++ } ++ ++ ospfAreaAggregateAreaID OBJECT-TYPE ++ SYNTAX AreaID ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The Area the Address Aggregate is to be found ++ within." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospfAreaAggregateEntry 1 } ++ ++ ++ ospfAreaAggregateLsdbType OBJECT-TYPE ++ SYNTAX INTEGER { ++ summaryLink (3), ++ nssaExternalLink (7) ++ } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The type of the Address Aggregate. This field ++ specifies the Lsdb type that this Address Ag- ++ gregate applies to." ++ REFERENCE ++ "OSPF Version 2, Appendix A.4.1 The Link State ++ Advertisement header" ++ ::= { ospfAreaAggregateEntry 2 } ++ ++ ++ ospfAreaAggregateNet OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP Address of the Net or Subnet indicated ++ by the range." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospfAreaAggregateEntry 3 } ++ ++ ++ ospfAreaAggregateMask OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The Subnet Mask that pertains to the Net or ++ Subnet." ++ REFERENCE ++ "OSPF Version 2, Appendix C.2 Area parameters" ++ ::= { ospfAreaAggregateEntry 4 } ++ ++ ++ ospfAreaAggregateStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This variable displays the status of the en- ++ try. Setting it to 'invalid' has the effect of ++ rendering it inoperative. The internal effect ++ (row removal) is implementation dependent." ++ ::= { ospfAreaAggregateEntry 5 } ++ ++ ++ ospfAreaAggregateEffect OBJECT-TYPE ++ SYNTAX INTEGER { ++ advertiseMatching (1), ++ doNotAdvertiseMatching (2) ++ } ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "Subnets subsumed by ranges either trigger the ++ advertisement of the indicated aggregate (ad- ++ vertiseMatching), or result in the subnet's not ++ being advertised at all outside the area." ++ DEFVAL { advertiseMatching } ++ ::= { ospfAreaAggregateEntry 6 } ++ ++ ++-- conformance information ++ ++ospfConformance OBJECT IDENTIFIER ::= { ospf 15 } ++ ++ospfGroups OBJECT IDENTIFIER ::= { ospfConformance 1 } ++ospfCompliances OBJECT IDENTIFIER ::= { ospfConformance 2 } ++ ++-- compliance statements ++ ++ ospfCompliance MODULE-COMPLIANCE ++ STATUS current ++ DESCRIPTION ++ "The compliance statement " ++ MODULE -- this module ++ MANDATORY-GROUPS { ++ ospfBasicGroup, ++ ospfAreaGroup, ++ ospfStubAreaGroup, ++ ospfIfGroup, ++ ospfIfMetricGroup, ++ ospfVirtIfGroup, ++ ospfNbrGroup, ++ ospfVirtNbrGroup, ++ ospfAreaAggregateGroup ++ } ++ ::= { ospfCompliances 1 } ++ ++ ++-- units of conformance ++ ++ ospfBasicGroup OBJECT-GROUP ++ OBJECTS { ++ ospfRouterId, ++ ospfAdminStat, ++ ospfVersionNumber, ++ ospfAreaBdrRtrStatus, ++ ospfASBdrRtrStatus, ++ ospfExternLsaCount, ++ ospfExternLsaCksumSum, ++ ospfTOSSupport, ++ ospfOriginateNewLsas, ++ ospfRxNewLsas, ++ ospfExtLsdbLimit, ++ ospfMulticastExtensions, ++ ospfExitOverflowInterval, ++ ospfDemandExtensions ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems." ++ ::= { ospfGroups 1 } ++ ++ ++ ospfAreaGroup OBJECT-GROUP ++ OBJECTS { ++ ospfAreaId, ++ ospfImportAsExtern, ++ ospfSpfRuns, ++ ospfAreaBdrRtrCount, ++ ospfAsBdrRtrCount, ++ ospfAreaLsaCount, ++ ospfAreaLsaCksumSum, ++ ospfAreaSummary, ++ ospfAreaStatus ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems ++ supporting areas." ++ ::= { ospfGroups 2 } ++ ++ ++ ospfStubAreaGroup OBJECT-GROUP ++ OBJECTS { ++ ospfStubAreaId, ++ ospfStubTOS, ++ ospfStubMetric, ++ ospfStubStatus, ++ ospfStubMetricType ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems ++ supporting stub areas." ++ ::= { ospfGroups 3 } ++ ++ ++ ospfLsdbGroup OBJECT-GROUP ++ OBJECTS { ++ ospfLsdbAreaId, ++ ospfLsdbType, ++ ospfLsdbLsid, ++ ospfLsdbRouterId, ++ ospfLsdbSequence, ++ ospfLsdbAge, ++ ospfLsdbChecksum, ++ ospfLsdbAdvertisement ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems ++ that display their link state database." ++ ::= { ospfGroups 4 } ++ ++ ++ ospfAreaRangeGroup OBJECT-GROUP ++ OBJECTS { ++ ospfAreaRangeAreaId, ++ ospfAreaRangeNet, ++ ospfAreaRangeMask, ++ ospfAreaRangeStatus, ++ ospfAreaRangeEffect ++ } ++ STATUS obsolete ++ DESCRIPTION ++ "These objects are required for non-CIDR OSPF ++ systems that support multiple areas." ++ ::= { ospfGroups 5 } ++ ++ ++ ospfHostGroup OBJECT-GROUP ++ OBJECTS { ++ ospfHostIpAddress, ++ ospfHostTOS, ++ ospfHostMetric, ++ ospfHostStatus, ++ ospfHostAreaID ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems ++ that support attached hosts." ++ ::= { ospfGroups 6 } ++ ++ ++ ospfIfGroup OBJECT-GROUP ++ OBJECTS { ++ ospfIfIpAddress, ++ ospfAddressLessIf, ++ ospfIfAreaId, ++ ospfIfType, ++ ospfIfAdminStat, ++ ospfIfRtrPriority, ++ ospfIfTransitDelay, ++ ospfIfRetransInterval, ++ ospfIfHelloInterval, ++ ospfIfRtrDeadInterval, ++ ospfIfPollInterval, ++ ospfIfState, ++ ospfIfDesignatedRouter, ++ ospfIfBackupDesignatedRouter, ++ ospfIfEvents, ++ ospfIfAuthType, ++ ospfIfAuthKey, ++ ospfIfStatus, ++ ospfIfMulticastForwarding, ++ ospfIfDemand ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems." ++ ::= { ospfGroups 7 } ++ ++ ++ ospfIfMetricGroup OBJECT-GROUP ++ OBJECTS { ++ ospfIfMetricIpAddress, ++ ospfIfMetricAddressLessIf, ++ ospfIfMetricTOS, ++ ospfIfMetricValue, ++ ospfIfMetricStatus ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems." ++ ::= { ospfGroups 8 } ++ ++ ++ ospfVirtIfGroup OBJECT-GROUP ++ OBJECTS { ++ ospfVirtIfAreaId, ++ ospfVirtIfNeighbor, ++ ospfVirtIfTransitDelay, ++ ospfVirtIfRetransInterval, ++ ospfVirtIfHelloInterval, ++ ospfVirtIfRtrDeadInterval, ++ ospfVirtIfState, ++ ospfVirtIfEvents, ++ ospfVirtIfAuthType, ++ ospfVirtIfAuthKey, ++ ospfVirtIfStatus ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems." ++ ::= { ospfGroups 9 } ++ ++ ++ ospfNbrGroup OBJECT-GROUP ++ OBJECTS { ++ ospfNbrIpAddr, ++ ospfNbrAddressLessIndex, ++ ospfNbrRtrId, ++ ospfNbrOptions, ++ ospfNbrPriority, ++ ospfNbrState, ++ ospfNbrEvents, ++ ospfNbrLsRetransQLen, ++ ospfNbmaNbrStatus, ++ ospfNbmaNbrPermanence, ++ ospfNbrHelloSuppressed ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems." ++ ::= { ospfGroups 10 } ++ ++ ++ ospfVirtNbrGroup OBJECT-GROUP ++ OBJECTS { ++ ospfVirtNbrArea, ++ ospfVirtNbrRtrId, ++ ospfVirtNbrIpAddr, ++ ospfVirtNbrOptions, ++ ospfVirtNbrState, ++ ospfVirtNbrEvents, ++ ospfVirtNbrLsRetransQLen, ++ ospfVirtNbrHelloSuppressed ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems." ++ ::= { ospfGroups 11 } ++ ++ ++ ospfExtLsdbGroup OBJECT-GROUP ++ OBJECTS { ++ ospfExtLsdbType, ++ ospfExtLsdbLsid, ++ ospfExtLsdbRouterId, ++ ospfExtLsdbSequence, ++ ospfExtLsdbAge, ++ ospfExtLsdbChecksum, ++ ospfExtLsdbAdvertisement ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems ++ that display their link state database." ++ ::= { ospfGroups 12 } ++ ++ ++ ospfAreaAggregateGroup OBJECT-GROUP ++ OBJECTS { ++ ospfAreaAggregateAreaID, ++ ospfAreaAggregateLsdbType, ++ ospfAreaAggregateNet, ++ ospfAreaAggregateMask, ++ ospfAreaAggregateStatus, ++ ospfAreaAggregateEffect ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required for OSPF systems." ++ ::= { ospfGroups 13 } ++ ++END +--- /dev/null ++++ b/mibs/OSPF-TRAP-MIB.txt +@@ -0,0 +1,443 @@ ++OSPF-TRAP-MIB DEFINITIONS ::= BEGIN ++ ++ IMPORTS ++ MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, IpAddress ++ FROM SNMPv2-SMI ++ MODULE-COMPLIANCE, OBJECT-GROUP ++ FROM SNMPv2-CONF ++ ospfRouterId, ospfIfIpAddress, ospfAddressLessIf, ospfIfState, ++ ospfVirtIfAreaId, ospfVirtIfNeighbor, ospfVirtIfState, ++ ospfNbrIpAddr, ospfNbrAddressLessIndex, ospfNbrRtrId, ++ ospfNbrState, ospfVirtNbrArea, ospfVirtNbrRtrId, ospfVirtNbrState, ++ ospfLsdbType, ospfLsdbLsid, ospfLsdbRouterId, ospfLsdbAreaId, ++ ospfExtLsdbLimit, ospf ++ FROM OSPF-MIB; ++ ++ ospfTrap MODULE-IDENTITY ++ LAST-UPDATED "9501201225Z" -- Fri Jan 20 12:25:50 PST 1995 ++ ORGANIZATION "IETF OSPF Working Group" ++ CONTACT-INFO ++ " Fred Baker ++ Postal: Cisco Systems ++ 519 Lado Drive ++ Santa Barbara, California 93111 ++ Tel: +1 805 681 0115 ++ E-Mail: fred@cisco.com ++ ++ Rob Coltun ++ Postal: RainbowBridge Communications ++ Tel: (301) 340-9416 ++ E-Mail: rcoltun@rainbow-bridge.com" ++ DESCRIPTION ++ "The MIB module to describe traps for the OSPF ++ Version 2 Protocol." ++ ::= { ospf 16 } ++ ++-- Trap Support Objects ++ ++-- The following are support objects for the OSPF traps. ++ ++ospfTrapControl OBJECT IDENTIFIER ::= { ospfTrap 1 } ++ospfTraps OBJECT IDENTIFIER ::= { ospfTrap 2 } ++ ++ ospfSetTrap OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE(4)) ++ MAX-ACCESS read-write ++ STATUS current ++ DESCRIPTION ++ "A four-octet string serving as a bit map for ++ the trap events defined by the OSPF traps. This ++ object is used to enable and disable specific ++ OSPF traps where a 1 in the bit field ++ represents enabled. The right-most bit (least ++ significant) represents trap 0." ++ ::= { ospfTrapControl 1 } ++ ++ ++ ospfConfigErrorType OBJECT-TYPE ++ SYNTAX INTEGER { ++ badVersion (1), ++ areaMismatch (2), ++ unknownNbmaNbr (3), -- Router is Dr eligible ++ unknownVirtualNbr (4), ++ authTypeMismatch(5), ++ authFailure (6), ++ netMaskMismatch (7), ++ helloIntervalMismatch (8), ++ deadIntervalMismatch (9), ++ optionMismatch (10) } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "Potential types of configuration conflicts. ++ Used by the ospfConfigError and ospfConfigVir- ++ tError traps." ++ ::= { ospfTrapControl 2 } ++ ++ ++ ospfPacketType OBJECT-TYPE ++ SYNTAX INTEGER { ++ hello (1), ++ dbDescript (2), ++ lsReq (3), ++ lsUpdate (4), ++ lsAck (5) } ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "OSPF packet types." ++ ::= { ospfTrapControl 3 } ++ ++ ++ ospfPacketSrc OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP address of an inbound packet that can- ++ not be identified by a neighbor instance." ++ ::= { ospfTrapControl 4 } ++ ++ ++-- Traps ++ ++ ++ ospfIfStateChange NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfIfIpAddress, ++ ospfAddressLessIf, ++ ospfIfState -- The new state ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfIfStateChange trap signifies that there ++ has been a change in the state of a non-virtual ++ OSPF interface. This trap should be generated ++ when the interface state regresses (e.g., goes ++ from Dr to Down) or progresses to a terminal ++ state (i.e., Point-to-Point, DR Other, Dr, or ++ Backup)." ++ ::= { ospfTraps 16 } ++ ++ ++ ospfVirtIfStateChange NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfVirtIfAreaId, ++ ospfVirtIfNeighbor, ++ ospfVirtIfState -- The new state ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfIfStateChange trap signifies that there ++ has been a change in the state of an OSPF vir- ++ tual interface. ++ This trap should be generated when the inter- ++ face state regresses (e.g., goes from Point- ++ to-Point to Down) or progresses to a terminal ++ state (i.e., Point-to-Point)." ++ ::= { ospfTraps 1 } ++ ++ ++ ospfNbrStateChange NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfNbrIpAddr, ++ ospfNbrAddressLessIndex, ++ ospfNbrRtrId, ++ ospfNbrState -- The new state ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfNbrStateChange trap signifies that ++ there has been a change in the state of a non- ++ virtual OSPF neighbor. This trap should be ++ generated when the neighbor state regresses ++ (e.g., goes from Attempt or Full to 1-Way or ++ Down) or progresses to a terminal state (e.g., ++ 2-Way or Full). When an neighbor transitions ++ from or to Full on non-broadcast multi-access ++ and broadcast networks, the trap should be gen- ++ erated by the designated router. A designated ++ router transitioning to Down will be noted by ++ ospfIfStateChange." ++ ::= { ospfTraps 2 } ++ ++ ++ ospfVirtNbrStateChange NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfVirtNbrArea, ++ ospfVirtNbrRtrId, ++ ospfVirtNbrState -- The new state ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfIfStateChange trap signifies that there ++ has been a change in the state of an OSPF vir- ++ tual neighbor. This trap should be generated ++ when the neighbor state regresses (e.g., goes ++ from Attempt or Full to 1-Way or Down) or ++ progresses to a terminal state (e.g., Full)." ++ ::= { ospfTraps 3 } ++ ospfIfConfigError NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfIfIpAddress, ++ ospfAddressLessIf, ++ ospfPacketSrc, -- The source IP address ++ ospfConfigErrorType, -- Type of error ++ ospfPacketType ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfIfConfigError trap signifies that a ++ packet has been received on a non-virtual in- ++ terface from a router whose configuration ++ parameters conflict with this router's confi- ++ guration parameters. Note that the event op- ++ tionMismatch should cause a trap only if it ++ prevents an adjacency from forming." ++ ::= { ospfTraps 4 } ++ ++ ++ ospfVirtIfConfigError NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfVirtIfAreaId, ++ ospfVirtIfNeighbor, ++ ospfConfigErrorType, -- Type of error ++ ospfPacketType ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfConfigError trap signifies that a pack- ++ et has been received on a virtual interface ++ from a router whose configuration parameters ++ conflict with this router's configuration ++ parameters. Note that the event optionMismatch ++ should cause a trap only if it prevents an ad- ++ jacency from forming." ++ ::= { ospfTraps 5 } ++ ++ ++ ospfIfAuthFailure NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfIfIpAddress, ++ ospfAddressLessIf, ++ ospfPacketSrc, -- The source IP address ++ ospfConfigErrorType, -- authTypeMismatch or ++ -- authFailure ++ ospfPacketType ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfIfAuthFailure trap signifies that a ++ packet has been received on a non-virtual in- ++ terface from a router whose authentication key ++ or authentication type conflicts with this ++ router's authentication key or authentication ++ type." ++ ::= { ospfTraps 6 } ++ ++ ++ ospfVirtIfAuthFailure NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfVirtIfAreaId, ++ ospfVirtIfNeighbor, ++ ospfConfigErrorType, -- authTypeMismatch or ++ -- authFailure ++ ospfPacketType ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfVirtIfAuthFailure trap signifies that a ++ packet has been received on a virtual interface ++ from a router whose authentication key or au- ++ thentication type conflicts with this router's ++ authentication key or authentication type." ++ ::= { ospfTraps 7 } ++ ++ ++ ospfIfRxBadPacket NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfIfIpAddress, ++ ospfAddressLessIf, ++ ospfPacketSrc, -- The source IP address ++ ospfPacketType ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfIfRxBadPacket trap signifies that an ++ OSPF packet has been received on a non-virtual ++ interface that cannot be parsed." ++ ::= { ospfTraps 8 } ++ ++ ospfVirtIfRxBadPacket NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfVirtIfAreaId, ++ ospfVirtIfNeighbor, ++ ospfPacketType ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfRxBadPacket trap signifies that an OSPF ++ packet has been received on a virtual interface ++ that cannot be parsed." ++ ::= { ospfTraps 9 } ++ ++ ++ ospfTxRetransmit NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfIfIpAddress, ++ ospfAddressLessIf, ++ ospfNbrRtrId, -- Destination ++ ospfPacketType, ++ ospfLsdbType, ++ ospfLsdbLsid, ++ ospfLsdbRouterId ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfTxRetransmit trap signifies than an ++ OSPF packet has been retransmitted on a non- ++ virtual interface. All packets that may be re- ++ transmitted are associated with an LSDB entry. ++ The LS type, LS ID, and Router ID are used to ++ identify the LSDB entry." ++ ::= { ospfTraps 10 } ++ ++ ++ ospfVirtIfTxRetransmit NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfVirtIfAreaId, ++ ospfVirtIfNeighbor, ++ ospfPacketType, ++ ospfLsdbType, ++ ospfLsdbLsid, ++ ospfLsdbRouterId ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfTxRetransmit trap signifies than an ++ OSPF packet has been retransmitted on a virtual ++ interface. All packets that may be retransmit- ++ ted are associated with an LSDB entry. The LS ++ type, LS ID, and Router ID are used to identify ++ the LSDB entry." ++ ::= { ospfTraps 11 } ++ ++ ++ ospfOriginateLsa NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfLsdbAreaId, -- 0.0.0.0 for AS Externals ++ ospfLsdbType, ++ ospfLsdbLsid, ++ ospfLsdbRouterId ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfOriginateLsa trap signifies that a new ++ LSA has been originated by this router. This ++ trap should not be invoked for simple refreshes ++ of LSAs (which happesn every 30 minutes), but ++ instead will only be invoked when an LSA is ++ (re)originated due to a topology change. Addi- ++ tionally, this trap does not include LSAs that ++ are being flushed because they have reached ++ MaxAge." ++ ::= { ospfTraps 12 } ++ ++ ++ ospfMaxAgeLsa NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfLsdbAreaId, -- 0.0.0.0 for AS Externals ++ ospfLsdbType, ++ ospfLsdbLsid, ++ ospfLsdbRouterId ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfMaxAgeLsa trap signifies that one of ++ the LSA in the router's link-state database has ++ aged to MaxAge." ++ ::= { ospfTraps 13 } ++ ++ ++ ospfLsdbOverflow NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfExtLsdbLimit ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfLsdbOverflow trap signifies that the ++ number of LSAs in the router's link-state data- ++ base has exceeded ospfExtLsdbLimit." ++ ::= { ospfTraps 14 } ++ ++ ++ ospfLsdbApproachingOverflow NOTIFICATION-TYPE ++ OBJECTS { ++ ospfRouterId, -- The originator of the trap ++ ospfExtLsdbLimit ++ } ++ STATUS current ++ DESCRIPTION ++ "An ospfLsdbApproachingOverflow trap signifies ++ that the number of LSAs in the router's link- ++ state database has exceeded ninety percent of ++ ospfExtLsdbLimit." ++ ::= { ospfTraps 15 } ++ ++ ++-- conformance information ++ ++ospfTrapConformance OBJECT IDENTIFIER ::= { ospfTrap 3 } ++ ++ospfTrapGroups OBJECT IDENTIFIER ::= { ospfTrapConformance 1 } ++ospfTrapCompliances OBJECT IDENTIFIER ::= { ospfTrapConformance 2 } ++ ++-- compliance statements ++ ++ ospfTrapCompliance MODULE-COMPLIANCE ++ STATUS current ++ DESCRIPTION ++ "The compliance statement " ++ MODULE -- this module ++ MANDATORY-GROUPS { ospfTrapControlGroup } ++ ++ ++ GROUP ospfTrapControlGroup ++ DESCRIPTION ++ "This group is optional but recommended for all ++ OSPF systems" ++ ::= { ospfTrapCompliances 1 } ++ ++ ++-- units of conformance ++ ++ ospfTrapControlGroup OBJECT-GROUP ++ OBJECTS { ++ ospfSetTrap, ++ ospfConfigErrorType, ++ ospfPacketType, ++ ospfPacketSrc ++ } ++ STATUS current ++ DESCRIPTION ++ "These objects are required to control traps ++ from OSPF systems." ++ ::= { ospfTrapGroups 1 } ++ ++ ++END +--- /dev/null ++++ b/mibs/RIPv2-MIB.txt +@@ -0,0 +1,530 @@ ++ RIPv2-MIB DEFINITIONS ::= BEGIN ++ ++ IMPORTS ++ MODULE-IDENTITY, OBJECT-TYPE, Counter32, ++ TimeTicks, IpAddress FROM SNMPv2-SMI ++ TEXTUAL-CONVENTION, RowStatus FROM SNMPv2-TC ++ MODULE-COMPLIANCE, OBJECT-GROUP FROM SNMPv2-CONF ++ mib-2 FROM RFC1213-MIB; ++ ++ -- This MIB module uses the extended OBJECT-TYPE macro as ++ -- defined in [9]. ++ ++ rip2 MODULE-IDENTITY ++ LAST-UPDATED "9407272253Z" -- Wed Jul 27 22:53:04 PDT 1994 ++ ORGANIZATION "IETF RIP-II Working Group" ++ CONTACT-INFO ++ " Fred Baker ++ Postal: Cisco Systems ++ 519 Lado Drive ++ Santa Barbara, California 93111 ++ Tel: +1 805 681 0115 ++ E-Mail: fbaker@cisco.com ++ ++ Postal: Gary Malkin ++ Xylogics, Inc. ++ 53 Third Avenue ++ Burlington, MA 01803 ++ ++ Phone: (617) 272-8140 ++ EMail: gmalkin@Xylogics.COM" ++ DESCRIPTION ++ "The MIB module to describe the RIP2 Version 2 Protocol" ++ ::= { mib-2 23 } ++ ++ -- RIP-2 Management Information Base ++ ++ -- the RouteTag type represents the contents of the ++ -- Route Domain field in the packet header or route entry. ++ -- The use of the Route Domain is deprecated. ++ ++ RouteTag ::= TEXTUAL-CONVENTION ++ STATUS current ++ DESCRIPTION ++ "the RouteTag type represents the contents of the Route Domain ++ field in the packet header or route entry" ++ SYNTAX OCTET STRING (SIZE (2)) ++ ++--4.1 Global Counters ++ ++-- The RIP-2 Globals Group. ++-- Implementation of this group is mandatory for systems ++-- which implement RIP-2. ++ ++-- These counters are intended to facilitate debugging quickly ++-- changing routes or failing neighbors ++ ++rip2Globals OBJECT IDENTIFIER ::= { rip2 1 } ++ ++ rip2GlobalRouteChanges OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of route changes made to the IP Route ++ Database by RIP. This does not include the refresh ++ of a route's age." ++ ::= { rip2Globals 1 } ++ ++ rip2GlobalQueries OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of responses sent to RIP queries ++ from other systems." ++ ::= { rip2Globals 2 } ++ ++--4.2 RIP Interface Tables ++ ++-- RIP Interfaces Groups ++-- Implementation of these Groups is mandatory for systems ++-- which implement RIP-2. ++ ++-- The RIP Interface Status Table. ++ ++ rip2IfStatTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF Rip2IfStatEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A list of subnets which require separate ++ status monitoring in RIP." ++ ::= { rip2 2 } ++ ++ rip2IfStatEntry OBJECT-TYPE ++ SYNTAX Rip2IfStatEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A Single Routing Domain in a single Subnet." ++ INDEX { rip2IfStatAddress } ++ ::= { rip2IfStatTable 1 } ++ ++ Rip2IfStatEntry ::= ++ SEQUENCE { ++ rip2IfStatAddress ++ IpAddress, ++ rip2IfStatRcvBadPackets ++ Counter32, ++ rip2IfStatRcvBadRoutes ++ Counter32, ++ rip2IfStatSentUpdates ++ Counter32, ++ rip2IfStatStatus ++ RowStatus ++ } ++ ++ rip2IfStatAddress OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP Address of this system on the indicated ++ subnet. For unnumbered interfaces, the value 0.0.0.N, ++ where the least significant 24 bits (N) is the ifIndex ++ for the IP Interface in network byte order." ++ ::= { rip2IfStatEntry 1 } ++ ++ rip2IfStatRcvBadPackets OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of RIP response packets received by ++ the RIP process which were subsequently discarded ++ for any reason (e.g. a version 0 packet, or an ++ unknown command type)." ++ ::= { rip2IfStatEntry 2 } ++ ++ rip2IfStatRcvBadRoutes OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of routes, in valid RIP packets, ++ which were ignored for any reason (e.g. unknown ++ address family, or invalid metric)." ++ ::= { rip2IfStatEntry 3 } ++ ++ rip2IfStatSentUpdates OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of triggered RIP updates actually ++ sent on this interface. This explicitly does ++ NOT include full updates sent containing new ++ information." ++ ::= { rip2IfStatEntry 4 } ++ ++ rip2IfStatStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "Writing invalid has the effect of deleting ++ this interface." ++ ::= { rip2IfStatEntry 5 } ++ ++-- The RIP Interface Configuration Table. ++ ++ rip2IfConfTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF Rip2IfConfEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A list of subnets which require separate ++ configuration in RIP." ++ ::= { rip2 3 } ++ ++ rip2IfConfEntry OBJECT-TYPE ++ SYNTAX Rip2IfConfEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A Single Routing Domain in a single Subnet." ++ INDEX { rip2IfConfAddress } ++ ::= { rip2IfConfTable 1 } ++ ++ Rip2IfConfEntry ::= ++ SEQUENCE { ++ rip2IfConfAddress ++ IpAddress, ++ rip2IfConfDomain ++ RouteTag, ++ rip2IfConfAuthType ++ INTEGER, ++ rip2IfConfAuthKey ++ OCTET STRING (SIZE(0..16)), ++ rip2IfConfSend ++ INTEGER, ++ rip2IfConfReceive ++ INTEGER, ++ rip2IfConfDefaultMetric ++ INTEGER, ++ rip2IfConfStatus ++ RowStatus, ++ rip2IfConfSrcAddress ++ IpAddress ++ } ++ ++ rip2IfConfAddress OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP Address of this system on the indicated ++ subnet. For unnumbered interfaces, the value 0.0.0.N, ++ where the least significant 24 bits (N) is the ifIndex ++ for the IP Interface in network byte order." ++ ::= { rip2IfConfEntry 1 } ++ ++ rip2IfConfDomain OBJECT-TYPE ++ SYNTAX RouteTag ++ MAX-ACCESS read-create ++ STATUS obsolete ++ DESCRIPTION ++ "Value inserted into the Routing Domain field ++ of all RIP packets sent on this interface." ++ DEFVAL { '0000'h } ++ ::= { rip2IfConfEntry 2 } ++ ++ rip2IfConfAuthType OBJECT-TYPE ++ SYNTAX INTEGER { ++ noAuthentication (1), ++ simplePassword (2), ++ md5 (3) ++ } ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The type of Authentication used on this ++ interface." ++ DEFVAL { noAuthentication } ++ ::= { rip2IfConfEntry 3 } ++ ++ rip2IfConfAuthKey OBJECT-TYPE ++ SYNTAX OCTET STRING (SIZE(0..16)) ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The value to be used as the Authentication Key ++ whenever the corresponding instance of ++ rip2IfConfAuthType has a value other than ++ noAuthentication. A modification of the corresponding ++ instance of rip2IfConfAuthType does not modify ++ the rip2IfConfAuthKey value. If a string shorter ++ than 16 octets is supplied, it will be left- ++ justified and padded to 16 octets, on the right, ++ with nulls (0x00). ++ ++ Reading this object always results in an OCTET ++ STRING of length zero; authentication may not ++ be bypassed by reading the MIB object." ++ DEFVAL { ''h } ++ ::= { rip2IfConfEntry 4 } ++ ++ rip2IfConfSend OBJECT-TYPE ++ SYNTAX INTEGER { ++ doNotSend (1), ++ ripVersion1 (2), ++ rip1Compatible (3), ++ ripVersion2 (4), ++ ripV1Demand (5), ++ ripV2Demand (6) ++ } ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "What the router sends on this interface. ++ ripVersion1 implies sending RIP updates compliant ++ with RFC 1058. rip1Compatible implies ++ broadcasting RIP-2 updates using RFC 1058 route ++ subsumption rules. ripVersion2 implies ++ multicasting RIP-2 updates. ripV1Demand indicates ++ the use of Demand RIP on a WAN interface under RIP ++ Version 1 rules. ripV2Demand indicates the use of ++ Demand RIP on a WAN interface under Version 2 rules." ++ DEFVAL { rip1Compatible } ++ ::= { rip2IfConfEntry 5 } ++ ++ rip2IfConfReceive OBJECT-TYPE ++ SYNTAX INTEGER { ++ rip1 (1), ++ rip2 (2), ++ rip1OrRip2 (3), ++ doNotRecieve (4) ++ } ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This indicates which version of RIP updates ++ are to be accepted. Note that rip2 and ++ rip1OrRip2 implies reception of multicast ++ packets." ++ DEFVAL { rip1OrRip2 } ++ ::= { rip2IfConfEntry 6 } ++ ++ rip2IfConfDefaultMetric OBJECT-TYPE ++ SYNTAX INTEGER ( 0..15 ) ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "This variable indicates the metric that is to ++ be used for the default route entry in RIP updates ++ originated on this interface. A value of zero ++ indicates that no default route should be ++ originated; in this case, a default route via ++ another router may be propagated." ++ ::= { rip2IfConfEntry 7 } ++ ++ rip2IfConfStatus OBJECT-TYPE ++ SYNTAX RowStatus ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "Writing invalid has the effect of deleting ++ this interface." ++ ::= { rip2IfConfEntry 8 } ++ ++ rip2IfConfSrcAddress OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-create ++ STATUS current ++ DESCRIPTION ++ "The IP Address this system will use as a source ++ address on this interface. If it is a numbered ++ interface, this MUST be the same value as ++ rip2IfConfAddress. On unnumbered interfaces, ++ it must be the value of rip2IfConfAddress for ++ some interface on the system." ++ ::= { rip2IfConfEntry 9 } ++ ++--4.3 Peer Table ++ ++-- Peer Table ++ ++-- The RIP Peer Group ++-- Implementation of this Group is Optional ++ ++-- This group provides information about active peer ++-- relationships intended to assist in debugging. An ++-- active peer is a router from which a valid RIP ++-- updated has been heard in the last 180 seconds. ++ ++ rip2PeerTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF Rip2PeerEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "A list of RIP Peers." ++ ::= { rip2 4 } ++ ++ rip2PeerEntry OBJECT-TYPE ++ SYNTAX Rip2PeerEntry ++ MAX-ACCESS not-accessible ++ STATUS current ++ DESCRIPTION ++ "Information regarding a single routing peer." ++ INDEX { rip2PeerAddress, rip2PeerDomain } ++ ::= { rip2PeerTable 1 } ++ ++ Rip2PeerEntry ::= ++ SEQUENCE { ++ rip2PeerAddress ++ IpAddress, ++ rip2PeerDomain ++ RouteTag, ++ rip2PeerLastUpdate ++ TimeTicks, ++ rip2PeerVersion ++ INTEGER, ++ rip2PeerRcvBadPackets ++ Counter32, ++ rip2PeerRcvBadRoutes ++ Counter32 ++ } ++ ++ rip2PeerAddress OBJECT-TYPE ++ SYNTAX IpAddress ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The IP Address that the peer is using as its source ++ address. Note that on an unnumbered link, this may ++ not be a member of any subnet on the system." ++ ::= { rip2PeerEntry 1 } ++ ++ rip2PeerDomain OBJECT-TYPE ++ SYNTAX RouteTag ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The value in the Routing Domain field in RIP ++ packets received from the peer. As domain suuport ++ is deprecated, this must be zero." ++ ::= { rip2PeerEntry 2 } ++ ++ rip2PeerLastUpdate OBJECT-TYPE ++ SYNTAX TimeTicks ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The value of sysUpTime when the most recent ++ RIP update was received from this system." ++ ::= { rip2PeerEntry 3 } ++ ++ rip2PeerVersion OBJECT-TYPE ++ SYNTAX INTEGER ( 0..255 ) ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The RIP version number in the header of the ++ last RIP packet received." ++ ::= { rip2PeerEntry 4 } ++ ++ rip2PeerRcvBadPackets OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of RIP response packets from this ++ peer discarded as invalid." ++ ::= { rip2PeerEntry 5 } ++ ++ ++ rip2PeerRcvBadRoutes OBJECT-TYPE ++ SYNTAX Counter32 ++ MAX-ACCESS read-only ++ STATUS current ++ DESCRIPTION ++ "The number of routes from this peer that were ++ ignored because the entry format was invalid." ++ ::= { rip2PeerEntry 6 } ++ ++-- conformance information ++ ++rip2Conformance OBJECT IDENTIFIER ::= { rip2 5 } ++ ++rip2Groups OBJECT IDENTIFIER ::= { rip2Conformance 1 } ++rip2Compliances OBJECT IDENTIFIER ::= { rip2Conformance 2 } ++ ++-- compliance statements ++rip2Compliance MODULE-COMPLIANCE ++ STATUS current ++ DESCRIPTION ++ "The compliance statement " ++ MODULE -- this module ++ MANDATORY-GROUPS { ++ rip2GlobalGroup, ++ rip2IfStatGroup, ++ rip2IfConfGroup, ++ rip2PeerGroup ++ } ++ GROUP rip2GlobalGroup ++ DESCRIPTION ++ "This group defines global controls for RIP-II systems." ++ GROUP rip2IfStatGroup ++ DESCRIPTION ++ "This group defines interface statistics for RIP-II systems." ++ GROUP rip2IfConfGroup ++ DESCRIPTION ++ "This group defines interface configuration for RIP-II systems." ++ GROUP rip2PeerGroup ++ DESCRIPTION ++ "This group defines peer information for RIP-II systems." ++ ::= { rip2Compliances 1 } ++ ++-- units of conformance ++ ++rip2GlobalGroup OBJECT-GROUP ++ OBJECTS { ++ rip2GlobalRouteChanges, ++ rip2GlobalQueries ++ } ++ STATUS current ++ DESCRIPTION ++ "This group defines global controls for RIP-II systems." ++ ::= { rip2Groups 1 } ++rip2IfStatGroup OBJECT-GROUP ++ OBJECTS { ++ rip2IfStatAddress, ++ rip2IfStatRcvBadPackets, ++ rip2IfStatRcvBadRoutes, ++ rip2IfStatSentUpdates, ++ rip2IfStatStatus ++ } ++ STATUS current ++ DESCRIPTION ++ "This group defines interface statistics for RIP-II systems." ++ ::= { rip2Groups 2 } ++rip2IfConfGroup OBJECT-GROUP ++ OBJECTS { ++ rip2IfConfAddress, ++ rip2IfConfAuthType, ++ rip2IfConfAuthKey, ++ rip2IfConfSend, ++ rip2IfConfReceive, ++ rip2IfConfDefaultMetric, ++ rip2IfConfStatus, ++ rip2IfConfSrcAddress ++ } ++ STATUS current ++ DESCRIPTION ++ "This group defines interface configuration for RIP-II systems." ++ ::= { rip2Groups 3 } ++rip2PeerGroup OBJECT-GROUP ++ OBJECTS { ++ rip2PeerAddress, ++ rip2PeerDomain, ++ rip2PeerLastUpdate, ++ rip2PeerVersion, ++ rip2PeerRcvBadPackets, ++ rip2PeerRcvBadRoutes ++ } ++ STATUS current ++ DESCRIPTION ++ "This group defines peer information for RIP-II systems." ++ ::= { rip2Groups 4 } ++END +--- /dev/null ++++ b/mibs/SOURCE-ROUTING-MIB.txt +@@ -0,0 +1,452 @@ ++SOURCE-ROUTING-MIB DEFINITIONS ::= BEGIN ++ ++IMPORTS ++ Counter, Gauge ++ FROM RFC1155-SMI ++ dot1dBridge, dot1dSr ++ FROM BRIDGE-MIB ++ OBJECT-TYPE ++ FROM RFC-1212; ++ ++-- groups in the SR MIB ++ ++-- dot1dSr is imported from the Bridge MIB ++ ++dot1dPortPair OBJECT IDENTIFIER ::= { dot1dBridge 10 } ++ ++-- the dot1dSr group ++ ++-- this group is implemented by those bridges that ++-- support the source route bridging mode, including Source ++-- Routing and SRT bridges. ++ ++dot1dSrPortTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF Dot1dSrPortEntry ++ ACCESS not-accessible ++ STATUS mandatory ++ DESCRIPTION ++ "A table that contains information about every ++ port that is associated with this source route ++ bridge." ++ ::= { dot1dSr 1 } ++ ++dot1dSrPortEntry OBJECT-TYPE ++ SYNTAX Dot1dSrPortEntry ++ ACCESS not-accessible ++ STATUS mandatory ++ DESCRIPTION ++ "A list of information for each port of a source ++ route bridge." ++ INDEX { dot1dSrPort } ++ ++ ::= { dot1dSrPortTable 1 } ++ ++Dot1dSrPortEntry ::= ++ SEQUENCE { ++ dot1dSrPort ++ INTEGER, ++ dot1dSrPortHopCount ++ INTEGER, ++ dot1dSrPortLocalSegment ++ INTEGER, ++ dot1dSrPortBridgeNum ++ INTEGER, ++ dot1dSrPortTargetSegment ++ INTEGER, ++ dot1dSrPortLargestFrame ++ INTEGER, ++ dot1dSrPortSTESpanMode ++ INTEGER, ++ dot1dSrPortSpecInFrames ++ Counter, ++ dot1dSrPortSpecOutFrames ++ Counter, ++ dot1dSrPortApeInFrames ++ Counter, ++ dot1dSrPortApeOutFrames ++ Counter, ++ dot1dSrPortSteInFrames ++ Counter, ++ dot1dSrPortSteOutFrames ++ Counter, ++ dot1dSrPortSegmentMismatchDiscards ++ Counter, ++ dot1dSrPortDuplicateSegmentDiscards ++ Counter, ++ dot1dSrPortHopCountExceededDiscards ++ Counter, ++ dot1dSrPortDupLanIdOrTreeErrors ++ Counter, ++ dot1dSrPortLanIdMismatches ++ Counter ++ } ++ ++dot1dSrPort OBJECT-TYPE ++ SYNTAX INTEGER (1..65535) ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The port number of the port for which this entry ++ ++ contains Source Route management information." ++ ::= { dot1dSrPortEntry 1 } ++ ++dot1dSrPortHopCount OBJECT-TYPE ++ SYNTAX INTEGER ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "The maximum number of routing descriptors allowed ++ in an All Paths or Spanning Tree Explorer frames." ++ ::= { dot1dSrPortEntry 2 } ++ ++dot1dSrPortLocalSegment OBJECT-TYPE ++ SYNTAX INTEGER ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "The segment number that uniquely identifies the ++ segment to which this port is connected. Current ++ source routing protocols limit this value to the ++ range: 0 through 4095. (The value 0 is used by ++ some management applications for special test ++ cases.) A value of 65535 signifies that no segment ++ number is assigned to this port." ++ ::= { dot1dSrPortEntry 3 } ++ ++dot1dSrPortBridgeNum OBJECT-TYPE ++ SYNTAX INTEGER ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "A bridge number uniquely identifies a bridge when ++ more than one bridge is used to span the same two ++ segments. Current source routing protocols limit ++ this value to the range: 0 through 15. A value of ++ 65535 signifies that no bridge number is assigned ++ to this bridge." ++ ::= { dot1dSrPortEntry 4 } ++ ++dot1dSrPortTargetSegment OBJECT-TYPE ++ SYNTAX INTEGER ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "The segment number that corresponds to the target ++ segment this port is considered to be connected to ++ by the bridge. Current source routing protocols ++ limit this value to the range: 0 through 4095. ++ ++ (The value 0 is used by some management ++ applications for special test cases.) A value of ++ 65535 signifies that no target segment is assigned ++ to this port." ++ ::= { dot1dSrPortEntry 5 } ++ ++-- It would be nice if we could use ifMtu as the size of the ++-- largest frame, but we can't because ifMtu is defined to be ++-- the size that the (inter-)network layer can use which can ++-- differ from the MAC layer (especially if several layers of ++-- encapsulation are used). ++ ++dot1dSrPortLargestFrame OBJECT-TYPE ++ SYNTAX INTEGER ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "The maximum size of the INFO field (LLC and ++ above) that this port can send/receive. It does ++ not include any MAC level (framing) octets. The ++ value of this object is used by this bridge to ++ determine whether a modification of the ++ LargestFrame (LF, see [14]) field of the Routing ++ Control field of the Routing Information Field is ++ necessary. ++ ++ 64 valid values are defined by the IEEE 802.5M SRT ++ Addendum: 516, 635, 754, 873, 993, 1112, 1231, ++ 1350, 1470, 1542, 1615, 1688, 1761, 1833, 1906, ++ 1979, 2052, 2345, 2638, 2932, 3225, 3518, 3812, ++ 4105, 4399, 4865, 5331, 5798, 6264, 6730, 7197, ++ 7663, 8130, 8539, 8949, 9358, 9768, 10178, 10587, ++ 10997, 11407, 12199, 12992, 13785, 14578, 15370, ++ 16163, 16956, 17749, 20730, 23711, 26693, 29674, ++ 32655, 35637, 38618, 41600, 44591, 47583, 50575, ++ 53567, 56559, 59551, and 65535. ++ ++ An illegal value will not be accepted by the ++ bridge." ++ ::= { dot1dSrPortEntry 6 } ++ ++dot1dSrPortSTESpanMode OBJECT-TYPE ++ SYNTAX INTEGER { ++ auto-span(1), ++ disabled(2), ++ forced(3) ++ } ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "Determines how this port behaves when presented ++ with a Spanning Tree Explorer frame. The value ++ 'disabled(2)' indicates that the port will not ++ accept or send Spanning Tree Explorer packets; any ++ STE packets received will be silently discarded. ++ The value 'forced(3)' indicates the port will ++ always accept and propagate Spanning Tree Explorer ++ frames. This allows a manually configured ++ Spanning Tree for this class of packet to be ++ configured. Note that unlike transparent ++ bridging, this is not catastrophic to the network ++ if there are loops. The value 'auto-span(1)' can ++ only be returned by a bridge that both implements ++ the Spanning Tree Protocol and has use of the ++ protocol enabled on this port. The behavior of the ++ port for Spanning Tree Explorer frames is ++ determined by the state of dot1dStpPortState. If ++ the port is in the 'forwarding' state, the frame ++ will be accepted or propagated. Otherwise, it ++ will be silently discarded." ++ ::= { dot1dSrPortEntry 7 } ++ ++dot1dSrPortSpecInFrames OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of Specifically Routed frames, also ++ referred to as Source Routed Frames, that have ++ been received from this port's segment." ++ ::= { dot1dSrPortEntry 8 } ++ ++dot1dSrPortSpecOutFrames OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of Specifically Routed frames, also ++ referred to as Source Routed Frames, that this ++ port has transmitted on its segment." ++ ::= { dot1dSrPortEntry 9 } ++ ++dot1dSrPortApeInFrames OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of All Paths Explorer frames, also ++ referred to as All Routes Explorer frames, that ++ have been received by this port from its segment." ++ ::= { dot1dSrPortEntry 10 } ++ ++dot1dSrPortApeOutFrames OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of all Paths Explorer Frames, also ++ referred to as All Routes Explorer frames, that ++ have been transmitted by this port on its ++ segment." ++ ::= { dot1dSrPortEntry 11 } ++ ++dot1dSrPortSteInFrames OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of spanning tree explorer frames that ++ have been received by this port from its segment." ++ ::= { dot1dSrPortEntry 12 } ++ ++dot1dSrPortSteOutFrames OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of spanning tree explorer frames that ++ have been transmitted by this port on its ++ segment." ++ ::= { dot1dSrPortEntry 13 } ++ ++dot1dSrPortSegmentMismatchDiscards OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of explorer frames that have been ++ discarded by this port because the routing ++ descriptor field contained an invalid adjacent ++ segment value." ++ ::= { dot1dSrPortEntry 14 } ++ ++dot1dSrPortDuplicateSegmentDiscards OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of frames that have been discarded by ++ this port because the routing descriptor field ++ contained a duplicate segment identifier." ++ ::= { dot1dSrPortEntry 15 } ++ ++dot1dSrPortHopCountExceededDiscards OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of explorer frames that have been ++ discarded by this port because the Routing ++ Information Field has exceeded the maximum route ++ descriptor length." ++ ::= { dot1dSrPortEntry 16 } ++ ++dot1dSrPortDupLanIdOrTreeErrors OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of duplicate LAN IDs or Tree errors. ++ This helps in detection of problems in networks ++ containing older IBM Source Routing Bridges." ++ ::= { dot1dSrPortEntry 17 } ++ ++dot1dSrPortLanIdMismatches OBJECT-TYPE ++ SYNTAX Counter ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The number of ARE and STE frames that were ++ discarded because the last LAN ID in the routing ++ information field did not equal the LAN-in ID. ++ This error can occur in implementations which do ++ only a LAN-in ID and Bridge Number check instead ++ of a LAN-in ID, Bridge Number, and LAN-out ID ++ check before they forward broadcast frames." ++ ::= { dot1dSrPortEntry 18 } ++ ++-- scalar object in dot1dSr ++ ++dot1dSrBridgeLfMode OBJECT-TYPE ++ SYNTAX INTEGER { ++ mode3(1), ++ mode6(2) ++ } ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "Indicates whether the bridge operates using older ++ 3 bit length negotiation fields or the newer 6 bit ++ length field in its RIF." ++ ::= { dot1dSr 2 } ++ ++-- The Port-Pair Database ++ ++-- Implementation of this group is optional. ++ ++-- This group is implemented by those bridges that support ++-- the direct multiport model of the source route bridging ++-- mode as defined in the IEEE 802.5 SRT Addendum to ++-- 802.1d. ++ ++-- Bridges implementing this group may report 65535 for ++-- dot1dSrPortBridgeNumber and dot1dSrPortTargetSegment, ++-- indicating that those objects are not applicable. ++ ++dot1dPortPairTableSize OBJECT-TYPE ++ SYNTAX Gauge ++ ACCESS read-only ++ STATUS mandatory ++ DESCRIPTION ++ "The total number of entries in the Bridge Port ++ Pair Database." ++ ::= { dot1dPortPair 1 } ++ ++-- the Bridge Port-Pair table ++ ++-- this table represents port pairs within a bridge forming ++-- a unique bridge path, as defined in the IEEE 802.5M SRT ++-- Addendum. ++ ++dot1dPortPairTable OBJECT-TYPE ++ SYNTAX SEQUENCE OF Dot1dPortPairEntry ++ ACCESS not-accessible ++ STATUS mandatory ++ DESCRIPTION ++ "A table that contains information about every ++ ++ port pair database entity associated with this ++ source routing bridge." ++ ::= { dot1dPortPair 2 } ++ ++dot1dPortPairEntry OBJECT-TYPE ++ SYNTAX Dot1dPortPairEntry ++ ACCESS not-accessible ++ STATUS mandatory ++ DESCRIPTION ++ "A list of information for each port pair entity ++ of a bridge." ++ INDEX { dot1dPortPairLowPort, dot1dPortPairHighPort } ++ ::= { dot1dPortPairTable 1 } ++ ++Dot1dPortPairEntry ::= ++ SEQUENCE { ++ dot1dPortPairLowPort ++ INTEGER, ++ dot1dPortPairHighPort ++ INTEGER, ++ dot1dPortPairBridgeNum ++ INTEGER, ++ dot1dPortPairBridgeState ++ INTEGER ++ } ++ ++dot1dPortPairLowPort OBJECT-TYPE ++ SYNTAX INTEGER (1..65535) ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "The port number of the lower numbered port for ++ which this entry contains port pair database ++ information." ++ ::= { dot1dPortPairEntry 1 } ++ ++dot1dPortPairHighPort OBJECT-TYPE ++ SYNTAX INTEGER (1..65535) ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "The port number of the higher numbered port for ++ which this entry contains port pair database ++ information." ++ ::= { dot1dPortPairEntry 2 } ++ ++dot1dPortPairBridgeNum OBJECT-TYPE ++ SYNTAX INTEGER ++ ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "A bridge number that uniquely identifies the path ++ provided by this source routing bridge between the ++ segments connected to dot1dPortPairLowPort and ++ dot1dPortPairHighPort. The purpose of bridge ++ number is to disambiguate between multiple paths ++ connecting the same two LANs." ++ ::= { dot1dPortPairEntry 3 } ++ ++dot1dPortPairBridgeState OBJECT-TYPE ++ SYNTAX INTEGER { ++ enabled(1), ++ disabled(2), ++ invalid(3) ++ } ++ ACCESS read-write ++ STATUS mandatory ++ DESCRIPTION ++ "The state of dot1dPortPairBridgeNum. Writing ++ 'invalid(3)' to this object removes the ++ corresponding entry." ++ ::= { dot1dPortPairEntry 4 } ++ ++END diff --git a/net-snmp-ssl/patches/160-no_ldconfig.patch b/net-snmp-ssl/patches/160-no_ldconfig.patch new file mode 100644 index 00000000..f6604dbe --- /dev/null +++ b/net-snmp-ssl/patches/160-no_ldconfig.patch @@ -0,0 +1,11 @@ +--- a/configure ++++ b/configure +@@ -16599,7 +16599,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' +- finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' ++ finish_cmds='' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + diff --git a/net-snmp-ssl/patches/161-project_types.patch b/net-snmp-ssl/patches/161-project_types.patch new file mode 100644 index 00000000..0818f5dd --- /dev/null +++ b/net-snmp-ssl/patches/161-project_types.patch @@ -0,0 +1,11 @@ +--- a/configure.d/config_project_types ++++ b/configure.d/config_project_types +@@ -66,7 +66,7 @@ netsnmp_save_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -Werror" + + AC_MSG_CHECKING([for the type of fd_set::fds_bits]) +-for type in __fd_mask __int32_t unknown; do ++for type in fd_mask int32_t size_t; do + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ + #include + #include diff --git a/net-snmp-ssl/patches/170-ldflags.patch b/net-snmp-ssl/patches/170-ldflags.patch new file mode 100644 index 00000000..f9781d80 --- /dev/null +++ b/net-snmp-ssl/patches/170-ldflags.patch @@ -0,0 +1,11 @@ +--- a/Makefile.top ++++ b/Makefile.top +@@ -87,7 +87,7 @@ LIBCURRENT = 42 + LIBAGE = 2 + LIBREVISION = 1 + +-LIB_LD_CMD = $(LIBTOOL) --mode=link $(LINKCC) $(CFLAGS) -rpath $(libdir) -version-info $(LIBCURRENT):$(LIBREVISION):$(LIBAGE) @LD_NO_UNDEFINED@ -o ++LIB_LD_CMD = $(LIBTOOL) --mode=link $(LINKCC) $(CFLAGS) -rpath $(libdir) $(LDFLAGS) -version-info $(LIBCURRENT):$(LIBREVISION):$(LIBAGE) @LD_NO_UNDEFINED@ -o + LIB_EXTENSION = la + LIB_VERSION = + LIB_LDCONFIG_CMD = $(LIBTOOL) --mode=finish $(INSTALL_PREFIX)$(libdir) diff --git a/net-snmp-ssl/patches/200-add-pcre2-support.patch b/net-snmp-ssl/patches/200-add-pcre2-support.patch new file mode 100644 index 00000000..1eed65e8 --- /dev/null +++ b/net-snmp-ssl/patches/200-add-pcre2-support.patch @@ -0,0 +1,407 @@ +From d3e95c87b32397815f6d5bcfc844259f2552697a Mon Sep 17 00:00:00 2001 +From: gagan sidhu +Date: Sun, 21 May 2023 15:47:36 -0600 +Subject: [PATCH] add pcre2 support + +--- + agent/mibgroup/host/data_access/swrun.c | 29 ++++++++++-- + agent/mibgroup/if-mib/data_access/interface.c | 47 ++++++++++++++++--- + agent/mibgroup/struct.h | 2 +- + agent/mibgroup/ucd-snmp/proc.c | 32 +++++++++---- + agent/mibgroup/ucd-snmp/proc.h | 2 +- + configure.d/config_os_libs1 | 27 +++++++++++ + configure.d/config_project_with_enable | 4 ++ + include/net-snmp/data_access/interface.h | 9 +++- + include/net-snmp/data_access/swrun.h | 2 +- + include/net-snmp/types.h | 2 +- + 10 files changed, 132 insertions(+), 24 deletions(-) + +--- a/agent/mibgroup/host/data_access/swrun.c ++++ b/agent/mibgroup/host/data_access/swrun.c +@@ -17,7 +17,10 @@ + #include "swrun.h" + #include "swrun_private.h" + +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include ++#elif defined(HAVE_PCRE_H) + #include + #endif + +@@ -100,32 +103,52 @@ swrun_max_processes( void ) + #endif /* NETSNMP_FEATURE_REMOVE_SWRUN_MAX_PROCESSES */ + + #ifndef NETSNMP_FEATURE_REMOVE_SWRUN_COUNT_PROCESSES_BY_REGEX +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + int + swrun_count_processes_by_regex( char *name, netsnmp_regex_ptr regexp ) + { + netsnmp_swrun_entry *entry; + netsnmp_iterator *it; + int i = 0; ++#ifdef HAVE_PCRE2_H ++ pcre2_match_data *ndx_match; ++ int *found_ndx; ++ ndx_match = pcre2_match_data_create(30, NULL); ++ found_ndx = pcre2_get_ovector_pointer(ndx_match); ++#elif defined(HAVE_PCRE_H) + int found_ndx[30]; ++#endif + int found; + char fullCommand[64 + 128 + 128 + 3]; + + netsnmp_cache_check_and_reload(swrun_cache); + if ( !swrun_container || !name || !regexp.regex_ptr ) ++#ifdef HAVE_PCRE2_H ++ { ++ pcre2_match_data_free(ndx_match); ++ return 0; ++ } ++#else + return 0; /* or -1 */ ++#endif + + it = CONTAINER_ITERATOR( swrun_container ); + while ((entry = (netsnmp_swrun_entry*)ITERATOR_NEXT( it )) != NULL) { + /* need to assemble full command back so regexps can get full picture */ + sprintf(fullCommand, "%s %s", entry->hrSWRunPath, entry->hrSWRunParameters); ++#ifdef HAVE_PCRE2_H ++ found = pcre2_match(regexp.regex_ptr, fullCommand, strlen(fullCommand), 0, 0, ndx_match, NULL); ++#elif HAVE_PCRE_H + found = pcre_exec(regexp.regex_ptr, NULL, fullCommand, strlen(fullCommand), 0, 0, found_ndx, 30); ++#endif + if (found > 0) { + i++; + } + } + ITERATOR_RELEASE( it ); +- ++#ifdef HAVE_PCRE2_H ++ pcre2_match_data_free(ndx_match); ++#endif + return i; + } + #endif /* HAVE_PCRE_H */ +--- a/agent/mibgroup/if-mib/data_access/interface.c ++++ b/agent/mibgroup/if-mib/data_access/interface.c +@@ -16,7 +16,11 @@ + #include "if-mib/ifTable/ifTable.h" + #include "if-mib/data_access/interface.h" + #include "interface_private.h" +-#if defined(HAVE_PCRE_H) ++ ++#if defined(HAVE_PCRE2_H) ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include ++#elif defined(HAVE_PCRE_H) + #include + #elif defined(HAVE_REGEX_H) + #include +@@ -824,7 +828,13 @@ int netsnmp_access_interface_max_reached + int netsnmp_access_interface_include(const char *name) + { + netsnmp_include_if_list *if_ptr; +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) ++ //pcre_exec->pcre2_match ++ //ovector->pcre2_match_data ++ pcre2_match_data *ndx_match; ++ ndx_match = pcre2_match_data_create(3, NULL); ++ int *found_ndx = pcre2_get_ovector_pointer(ndx_match); ++#elif defined(HAVE_PCRE_H) + int found_ndx[3]; + #endif + +@@ -840,7 +850,13 @@ int netsnmp_access_interface_include(con + + + for (if_ptr = include_list; if_ptr; if_ptr = if_ptr->next) { +-#if defined(HAVE_PCRE_H) ++#if defined(HAVE_PCRE2_H) ++ if (pcre2_match(if_ptr->regex_ptr, name, strlen(name), 0, 0, ++ ndx_match, NULL) >= 0) { ++ pcre2_match_data_free(ndx_match); ++ return TRUE; ++ } ++#elif defined(HAVE_PCRE_H) + if (pcre_exec(if_ptr->regex_ptr, NULL, name, strlen(name), 0, 0, + found_ndx, 3) >= 0) + return TRUE; +@@ -853,6 +869,9 @@ int netsnmp_access_interface_include(con + #endif + } + ++#if defined(HAVE_PCRE2_H) ++ pcre2_match_data_free(ndx_match); ++#endif + return FALSE; + } + +@@ -964,7 +983,13 @@ _parse_include_if_config(const char *tok + { + netsnmp_include_if_list *if_ptr, *if_new; + char *name, *st; +-#if defined(HAVE_PCRE_H) ++#if defined(HAVE_PCRE2_H) ++ //we can only get the message upon calling pcre2_error_message. ++ // so an additional variable is required. ++ int pcre2_err_code; ++ unsigned char pcre2_error[128]; ++ int pcre2_error_offset; ++#elif defined(HAVE_PCRE_H) + const char *pcre_error; + int pcre_error_offset; + #elif defined(HAVE_REGEX_H) +@@ -996,7 +1021,15 @@ _parse_include_if_config(const char *tok + config_perror("Out of memory"); + goto err; + } +-#if defined(HAVE_PCRE_H) ++#if defined(HAVE_PCRE2_H) ++ if_new->regex_ptr = pcre2_compile(if_new->name, PCRE2_ZERO_TERMINATED, 0, ++ &pcre2_err_code, &pcre2_error_offset, NULL); ++ if (!if_new->regex_ptr) { ++ pcre2_get_error_message(pcre2_err_code, pcre2_error, 128); ++ config_perror(pcre2_error); ++ goto err; ++ } ++#elif defined(HAVE_PCRE_H) + if_new->regex_ptr = pcre_compile(if_new->name, 0, &pcre_error, + &pcre_error_offset, NULL); + if (!if_new->regex_ptr) { +@@ -1032,7 +1065,7 @@ _parse_include_if_config(const char *tok + + err: + if (if_new) { +-#if defined(HAVE_PCRE_H) || defined(HAVE_REGEX_H) ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) || defined(HAVE_REGEX_H) + free(if_new->regex_ptr); + #endif + free(if_new->name); +@@ -1047,7 +1080,7 @@ _free_include_if_config(void) + + while (if_ptr) { + if_next = if_ptr->next; +-#if defined(HAVE_PCRE_H) ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + free(if_ptr->regex_ptr); + #elif defined(HAVE_REGEX_H) + regfree(if_ptr->regex_ptr); +--- a/agent/mibgroup/struct.h ++++ b/agent/mibgroup/struct.h +@@ -30,7 +30,7 @@ struct extensible { + + struct myproc { + char name[STRMAX]; +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + netsnmp_regex_ptr regexp; + #endif + char fixcmd[STRMAX]; +--- a/agent/mibgroup/ucd-snmp/proc.c ++++ b/agent/mibgroup/ucd-snmp/proc.c +@@ -39,7 +39,10 @@ + # include + # endif + #endif +-#ifdef HAVE_PCRE_H ++#ifdef HAVE_PCRE2_H ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include ++#elifdef HAVE_PCRE_H + #include + #endif + +@@ -108,7 +111,7 @@ init_proc(void) + REGISTER_MIB("ucd-snmp/proc", extensible_proc_variables, variable2, + proc_variables_oid); + +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + #define proc_parse_usage "process-name [max-num] [min-num] [regexp]" + #else + #define proc_parse_usage "process-name [max-num] [min-num]" +@@ -134,7 +137,7 @@ proc_free_config(void) + for (ptmp = procwatch; ptmp != NULL;) { + ptmp2 = ptmp; + ptmp = ptmp->next; +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + free(ptmp2->regexp.regex_ptr); + #endif + free(ptmp2); +@@ -208,7 +211,7 @@ proc_parse_config(const char *token, cha + if (*procp == NULL) + return; /* memory alloc error */ + numprocs++; +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + (*procp)->regexp.regex_ptr = NULL; + #endif + /* +@@ -220,18 +223,31 @@ proc_parse_config(const char *token, cha + cptr = skip_not_white(cptr); + if ((cptr = skip_white(cptr))) { + (*procp)->min = atoi(cptr); +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + cptr = skip_not_white(cptr); + if ((cptr = skip_white(cptr))) { ++ DEBUGMSGTL(("ucd-snmp/regexp_proc", "Loading regex %s\n", cptr)); ++#ifdef HAVE_PCRE2_H ++ unsigned char pcre2_error_msg[128]; ++ int pcre2_err_code; ++ int pcre2_error_offset; ++ ++ (*procp)->regexp.regex_ptr = ++ pcre2_compile(cptr, PCRE2_ZERO_TERMINATED, 0, &pcre2_err_code, &pcre2_error_offset, NULL); ++ pcre2_get_error_message(pcre2_err_code, pcre2_error_msg, 128); ++ if ((*procp)->regexp.regex_ptr == NULL) { ++ config_perror(pcre2_error_msg); ++ } ++#elifdef HAVE_PCRE_H + const char *pcre_error; + int pcre_error_offset; + +- DEBUGMSGTL(("ucd-snmp/regexp_proc", "Loading regex %s\n", cptr)); + (*procp)->regexp.regex_ptr = + pcre_compile(cptr, 0, &pcre_error, &pcre_error_offset, NULL); + if ((*procp)->regexp.regex_ptr == NULL) { + config_perror(pcre_error); + } ++#endif + } + #endif + } else +@@ -390,7 +406,7 @@ sh_count_myprocs(struct myproc *proc) + if (proc == NULL) + return 0; + +-#if defined(USING_HOST_DATA_ACCESS_SWRUN_MODULE) && defined(HAVE_PCRE_H) ++#if defined(USING_HOST_DATA_ACCESS_SWRUN_MODULE) && (defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H)) + if (proc->regexp.regex_ptr != NULL) + return sh_count_procs_by_regex(proc->name, proc->regexp); + #endif +@@ -406,7 +422,7 @@ sh_count_procs(char *procname) + return swrun_count_processes_by_name( procname ); + } + +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + netsnmp_feature_require(swrun_count_processes_by_regex); + int + sh_count_procs_by_regex(char *procname, netsnmp_regex_ptr regexp) +--- a/agent/mibgroup/ucd-snmp/proc.h ++++ b/agent/mibgroup/ucd-snmp/proc.h +@@ -12,7 +12,7 @@ config_require(util_funcs); + extern WriteMethod fixProcError; + int sh_count_myprocs(struct myproc *); + int sh_count_procs(char *); +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + int sh_count_procs_by_regex(char *, netsnmp_regex_ptr); + #endif + +--- a/configure.d/config_os_libs1 ++++ b/configure.d/config_os_libs1 +@@ -97,6 +97,32 @@ LIBS="$netsnmp_save_LIBS" + # + # regex in process table + # ++if test "x$with_pcre2" != "xno"; then ++ AC_CHECK_HEADER([pcre2.h], [ ++ AC_DEFINE([HAVE_PCRE2_H], [1], [Define to 1 if you have .]) ++ pcre2_h=yes ++ ], ++ [pcre2_h=no], [#define PCRE2_CODE_UNIT_WIDTH 8] ++ ) ++fi ++if test "x$pcre2header_h" = "xno" -o "x$pcre2_h" = "xno" ; then ++ if test "x$with_pcre2" = "xyes" ; then ++ AC_MSG_ERROR([Could not find the pcre2 header file needed and was specifically asked to use pcre2 support]) ++ else ++ with_pcre2=no ++ fi ++fi ++ ++if test "x$with_pcre2" != "xno"; then ++ NETSNMP_SEARCH_LIBS([pcre2_match_8], [pcre2-8], [ ++ LMIBLIBS="$LMIBLIBS -lpcre2-8" ++ ],,, LAGENTLIBS) ++ AC_SUBST(LAGENTLIBS) ++ AC_SUBST(LMIBLIBS) ++fi ++ ++if test "x$with_pcre2" != "xyes"; then ++ + if test "x$with_pcre" != "xno"; then + AC_CHECK_HEADER([pcre.h], [ + AC_DEFINE([HAVE_PCRE_H], [1], [Define to 1 if you have .]) +@@ -123,3 +149,4 @@ if test "x$with_pcre" != "xno"; then + AC_SUBST(LAGENTLIBS) + AC_SUBST(LMIBLIBS) + fi ++fi +--- a/configure.d/config_project_with_enable ++++ b/configure.d/config_project_with_enable +@@ -160,6 +160,10 @@ NETSNMP_ARG_WITH(rpm, + management system when building the host MIB + module.]) + ++NETSNMP_ARG_WITH(pcre2-8, ++[ --without-pcre2 Don't include pcre2 process searching ++ support in the agent.], ++ with_pcre2="$withval", with_pcre2="maybe") + + NETSNMP_ARG_WITH(pcre, + [ --without-pcre Don't include pcre process searching +--- a/include/net-snmp/data_access/interface.h ++++ b/include/net-snmp/data_access/interface.h +@@ -10,7 +10,10 @@ + extern "C" { + #endif + +-#if defined(HAVE_PCRE_H) ++#if defined(HAVE_PCRE2_H) ++#define PCRE2_CODE_UNIT_WIDTH 8 ++#include ++#elif defined(HAVE_PCRE_H) + #include + #elif defined(HAVE_REGEX_H) + #include +@@ -211,7 +214,9 @@ typedef struct _conf_if_list { + typedef netsnmp_conf_if_list conf_if_list; /* backwards compat */ + + typedef struct _include_if_list { +-#if defined(HAVE_PCRE_H) ++#if defined(HAVE_PCRE2_H) ++ pcre2_code *regex_ptr; ++#elif defined(HAVE_PCRE_H) + pcre *regex_ptr; + #elif defined(HAVE_REGEX_H) + regex_t *regex_ptr; +--- a/include/net-snmp/data_access/swrun.h ++++ b/include/net-snmp/data_access/swrun.h +@@ -90,7 +90,7 @@ extern "C" { + int swrun_count_processes_by_name( char *name ); + + #if !defined(NETSNMP_FEATURE_REMOVE_SWRUN_COUNT_PROCESSES_BY_REGEX) \ +- && defined(HAVE_PCRE_H) ++ && (defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H)) + int swrun_count_processes_by_regex(char *name, netsnmp_regex_ptr regexp); + #endif + +--- a/include/net-snmp/types.h ++++ b/include/net-snmp/types.h +@@ -63,7 +63,7 @@ typedef long ssize_t; + typedef unsigned long int nfds_t; + #endif + +-#ifdef HAVE_PCRE_H ++#if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + /* + * Abstract the pcre typedef such that not all *.c files have to include + * . diff --git a/net-snmp-ssl/patches/201-Run-autoreconf.patch b/net-snmp-ssl/patches/201-Run-autoreconf.patch new file mode 100644 index 00000000..0417dff2 --- /dev/null +++ b/net-snmp-ssl/patches/201-Run-autoreconf.patch @@ -0,0 +1,185 @@ +From 48b313ca34dbdf303fb232191d4f74e1d0fc9f06 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Sun, 21 May 2023 16:20:15 -0700 +Subject: [PATCH] Run autoreconf + +--- + configure | 126 ++++++++++++++++++++++++++ + include/net-snmp/net-snmp-config.h.in | 3 + + 2 files changed, 129 insertions(+) + +--- a/configure ++++ b/configure +@@ -928,6 +928,8 @@ with_dnssec + enable_dnssec + with_rpm + enable_rpm ++with_pcre2_8 ++enable_pcre2_8 + with_pcre + enable_pcre + with_install_prefix +@@ -1851,6 +1853,8 @@ Compiler Options: + --without-rpm Don't include support for the RPM package + management system when building the host MIB + module. ++ --without-pcre2 Don't include pcre2 process searching ++ support in the agent. + --without-pcre Don't include pcre process searching + support in the agent. + --with-install-prefix=PATH Just for installing, prefix all +@@ -5259,6 +5263,21 @@ fi + + + ++# Check whether --with-pcre2-8 was given. ++if test ${with_pcre2_8+y} ++then : ++ withval=$with_pcre2_8; with_pcre2="$withval" ++else $as_nop ++ with_pcre2="maybe" ++fi ++ ++ # Check whether --enable-pcre2-8 was given. ++if test ${enable_pcre2_8+y} ++then : ++ enableval=$enable_pcre2_8; as_fn_error $? "Invalid option. Use --with-pcre2-8/--without-pcre2-8 instead" "$LINENO" 5 ++fi ++ ++ + + # Check whether --with-pcre was given. + if test ${with_pcre+y} +@@ -26477,6 +26496,112 @@ LIBS="$netsnmp_save_LIBS" + # + # regex in process table + # ++if test "x$with_pcre2" != "xno"; then ++ ac_fn_c_check_header_compile "$LINENO" "pcre2.h" "ac_cv_header_pcre2_h" "#define PCRE2_CODE_UNIT_WIDTH 8 ++ ++" ++if test "x$ac_cv_header_pcre2_h" = xyes ++then : ++ ++ ++printf "%s\n" "#define HAVE_PCRE2_H 1" >>confdefs.h ++ ++ pcre2_h=yes ++ ++else $as_nop ++ pcre2_h=no ++fi ++ ++fi ++if test "x$pcre2header_h" = "xno" -o "x$pcre2_h" = "xno" ; then ++ if test "x$with_pcre2" = "xyes" ; then ++ as_fn_error $? "Could not find the pcre2 header file needed and was specifically asked to use pcre2 support" "$LINENO" 5 ++ else ++ with_pcre2=no ++ fi ++fi ++ ++if test "x$with_pcre2" != "xno"; then ++ ++ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing pcre2_match_8" >&5 ++printf %s "checking for library containing pcre2_match_8... " >&6; } ++if test ${netsnmp_cv_func_pcre2_match_8_LAGENTLIBS+y} ++then : ++ printf %s "(cached) " >&6 ++else $as_nop ++ netsnmp_func_search_save_LIBS="$LIBS" ++ netsnmp_target_val="$LAGENTLIBS" ++ netsnmp_temp_LIBS="${netsnmp_target_val} ${LIBS}" ++ netsnmp_result=no ++ LIBS="${netsnmp_temp_LIBS}" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++char pcre2_match_8 (); ++int ++main (void) ++{ ++return pcre2_match_8 (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO" ++then : ++ netsnmp_result="none required" ++else $as_nop ++ for netsnmp_cur_lib in pcre2-8 ; do ++ LIBS="-l${netsnmp_cur_lib} ${netsnmp_temp_LIBS}" ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++char pcre2_match_8 (); ++int ++main (void) ++{ ++return pcre2_match_8 (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO" ++then : ++ netsnmp_result=-l${netsnmp_cur_lib} ++ break ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.beam \ ++ conftest$ac_exeext conftest.$ac_ext ++ done ++fi ++rm -f core conftest.err conftest.$ac_objext conftest.beam \ ++ conftest$ac_exeext conftest.$ac_ext ++ LIBS="${netsnmp_func_search_save_LIBS}" ++ netsnmp_cv_func_pcre2_match_8_LAGENTLIBS="${netsnmp_result}" ++fi ++{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $netsnmp_cv_func_pcre2_match_8_LAGENTLIBS" >&5 ++printf "%s\n" "$netsnmp_cv_func_pcre2_match_8_LAGENTLIBS" >&6; } ++ if test "${netsnmp_cv_func_pcre2_match_8_LAGENTLIBS}" != "no" ; then ++ if test "${netsnmp_cv_func_pcre2_match_8_LAGENTLIBS}" != "none required" ; then ++ LAGENTLIBS="${netsnmp_result} ${netsnmp_target_val}" ++ fi ++ ++ LMIBLIBS="$LMIBLIBS -lpcre2-8" ++ ++ ++ fi ++ ++ ++ ++fi ++ ++if test "x$with_pcre2" != "xyes"; then ++ + if test "x$with_pcre" != "xno"; then + ac_fn_c_check_header_compile "$LINENO" "pcre.h" "ac_cv_header_pcre_h" "$ac_includes_default" + if test "x$ac_cv_header_pcre_h" = xyes +@@ -31486,6 +31611,7 @@ printf "%s\n" "#define pid_t $ac_pid_typ + + + fi ++fi + + + +--- a/include/net-snmp/net-snmp-config.h.in ++++ b/include/net-snmp/net-snmp-config.h.in +@@ -727,6 +727,9 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_PCI_PCI_H + ++/* Define to 1 if you have . */ ++#undef HAVE_PCRE2_H ++ + /* Define to 1 if you have . */ + #undef HAVE_PCRE_H + diff --git a/net-snmp-ssl/patches/202-Improve-pcre2-support.patch b/net-snmp-ssl/patches/202-Improve-pcre2-support.patch new file mode 100644 index 00000000..067adcbf --- /dev/null +++ b/net-snmp-ssl/patches/202-Improve-pcre2-support.patch @@ -0,0 +1,152 @@ +From 346b6f8959513320e5b674fd670c49ba2cd43af5 Mon Sep 17 00:00:00 2001 +From: Bart Van Assche +Date: Sun, 21 May 2023 16:18:56 -0700 +Subject: [PATCH] Improve pcre2 support + +Fix compiler warnings. Convert C++ comments to C comments. Make sure that +declarations occur before statements. +--- + agent/mibgroup/host/data_access/swrun.c | 17 ++++------ + agent/mibgroup/if-mib/data_access/interface.c | 32 ++++++++++--------- + agent/mibgroup/ucd-snmp/proc.c | 13 +++++--- + 3 files changed, 31 insertions(+), 31 deletions(-) + +--- a/agent/mibgroup/host/data_access/swrun.c ++++ b/agent/mibgroup/host/data_access/swrun.c +@@ -111,10 +111,7 @@ swrun_count_processes_by_regex( char *na + netsnmp_iterator *it; + int i = 0; + #ifdef HAVE_PCRE2_H +- pcre2_match_data *ndx_match; +- int *found_ndx; +- ndx_match = pcre2_match_data_create(30, NULL); +- found_ndx = pcre2_get_ovector_pointer(ndx_match); ++ pcre2_match_data *ndx_match = pcre2_match_data_create(30, NULL); + #elif defined(HAVE_PCRE_H) + int found_ndx[30]; + #endif +@@ -122,22 +119,20 @@ swrun_count_processes_by_regex( char *na + char fullCommand[64 + 128 + 128 + 3]; + + netsnmp_cache_check_and_reload(swrun_cache); +- if ( !swrun_container || !name || !regexp.regex_ptr ) ++ if ( !swrun_container || !name || !regexp.regex_ptr ) { + #ifdef HAVE_PCRE2_H +- { + pcre2_match_data_free(ndx_match); +- return 0; +- } +-#else +- return 0; /* or -1 */ + #endif ++ return 0; /* or -1 */ ++ } + + it = CONTAINER_ITERATOR( swrun_container ); + while ((entry = (netsnmp_swrun_entry*)ITERATOR_NEXT( it )) != NULL) { + /* need to assemble full command back so regexps can get full picture */ + sprintf(fullCommand, "%s %s", entry->hrSWRunPath, entry->hrSWRunParameters); + #ifdef HAVE_PCRE2_H +- found = pcre2_match(regexp.regex_ptr, fullCommand, strlen(fullCommand), 0, 0, ndx_match, NULL); ++ found = pcre2_match(regexp.regex_ptr, (unsigned char *)fullCommand, ++ strlen(fullCommand), 0, 0, ndx_match, NULL); + #elif HAVE_PCRE_H + found = pcre_exec(regexp.regex_ptr, NULL, fullCommand, strlen(fullCommand), 0, 0, found_ndx, 30); + #endif +--- a/agent/mibgroup/if-mib/data_access/interface.c ++++ b/agent/mibgroup/if-mib/data_access/interface.c +@@ -828,12 +828,8 @@ int netsnmp_access_interface_max_reached + int netsnmp_access_interface_include(const char *name) + { + netsnmp_include_if_list *if_ptr; +-#if defined(HAVE_PCRE2_H) +- //pcre_exec->pcre2_match +- //ovector->pcre2_match_data +- pcre2_match_data *ndx_match; +- ndx_match = pcre2_match_data_create(3, NULL); +- int *found_ndx = pcre2_get_ovector_pointer(ndx_match); ++#if defined(HAVE_PCRE2_H) ++ pcre2_match_data *ndx_match = pcre2_match_data_create(3, NULL); + #elif defined(HAVE_PCRE_H) + int found_ndx[3]; + #endif +@@ -851,8 +847,8 @@ int netsnmp_access_interface_include(con + + for (if_ptr = include_list; if_ptr; if_ptr = if_ptr->next) { + #if defined(HAVE_PCRE2_H) +- if (pcre2_match(if_ptr->regex_ptr, name, strlen(name), 0, 0, +- ndx_match, NULL) >= 0) { ++ if (pcre2_match(if_ptr->regex_ptr, (const unsigned char *)name, ++ strlen(name), 0, 0, ndx_match, NULL) >= 0) { + pcre2_match_data_free(ndx_match); + return TRUE; + } +@@ -984,11 +980,13 @@ _parse_include_if_config(const char *tok + netsnmp_include_if_list *if_ptr, *if_new; + char *name, *st; + #if defined(HAVE_PCRE2_H) +- //we can only get the message upon calling pcre2_error_message. +- // so an additional variable is required. ++ /* ++ * We can only get the message upon calling pcre2_error_message. ++ * so an additional variable is required. ++ */ + int pcre2_err_code; +- unsigned char pcre2_error[128]; +- int pcre2_error_offset; ++ char pcre2_error[128]; ++ size_t pcre2_error_offset; + #elif defined(HAVE_PCRE_H) + const char *pcre_error; + int pcre_error_offset; +@@ -1022,10 +1020,14 @@ _parse_include_if_config(const char *tok + goto err; + } + #if defined(HAVE_PCRE2_H) +- if_new->regex_ptr = pcre2_compile(if_new->name, PCRE2_ZERO_TERMINATED, 0, +- &pcre2_err_code, &pcre2_error_offset, NULL); ++ if_new->regex_ptr = pcre2_compile((const unsigned char *)if_new->name, ++ PCRE2_ZERO_TERMINATED, 0, ++ &pcre2_err_code, &pcre2_error_offset, ++ NULL); + if (!if_new->regex_ptr) { +- pcre2_get_error_message(pcre2_err_code, pcre2_error, 128); ++ pcre2_get_error_message(pcre2_err_code, ++ (unsigned char *)pcre2_error, ++ sizeof(pcre2_error)); + config_perror(pcre2_error); + goto err; + } +--- a/agent/mibgroup/ucd-snmp/proc.c ++++ b/agent/mibgroup/ucd-snmp/proc.c +@@ -226,15 +226,17 @@ proc_parse_config(const char *token, cha + #if defined(HAVE_PCRE2_H) || defined(HAVE_PCRE_H) + cptr = skip_not_white(cptr); + if ((cptr = skip_white(cptr))) { +- DEBUGMSGTL(("ucd-snmp/regexp_proc", "Loading regex %s\n", cptr)); + #ifdef HAVE_PCRE2_H +- unsigned char pcre2_error_msg[128]; ++ char pcre2_error_msg[128]; + int pcre2_err_code; +- int pcre2_error_offset; ++ size_t pcre2_error_offset; + ++ DEBUGMSGTL(("ucd-snmp/regexp_proc", "Loading regex %s\n", cptr)); + (*procp)->regexp.regex_ptr = +- pcre2_compile(cptr, PCRE2_ZERO_TERMINATED, 0, &pcre2_err_code, &pcre2_error_offset, NULL); +- pcre2_get_error_message(pcre2_err_code, pcre2_error_msg, 128); ++ pcre2_compile((const unsigned char *)cptr, PCRE2_ZERO_TERMINATED, 0, &pcre2_err_code, &pcre2_error_offset, NULL); ++ pcre2_get_error_message(pcre2_err_code, ++ (unsigned char *)pcre2_error_msg, ++ sizeof(pcre2_error_msg)); + if ((*procp)->regexp.regex_ptr == NULL) { + config_perror(pcre2_error_msg); + } +@@ -242,6 +244,7 @@ proc_parse_config(const char *token, cha + const char *pcre_error; + int pcre_error_offset; + ++ DEBUGMSGTL(("ucd-snmp/regexp_proc", "Loading regex %s\n", cptr)); + (*procp)->regexp.regex_ptr = + pcre_compile(cptr, 0, &pcre_error, &pcre_error_offset, NULL); + if ((*procp)->regexp.regex_ptr == NULL) { diff --git a/net-snmp-ssl/patches/203-if-mib-data_access-interface.c-plug-a-leak-with-pcre.patch b/net-snmp-ssl/patches/203-if-mib-data_access-interface.c-plug-a-leak-with-pcre.patch new file mode 100644 index 00000000..71b553b7 --- /dev/null +++ b/net-snmp-ssl/patches/203-if-mib-data_access-interface.c-plug-a-leak-with-pcre.patch @@ -0,0 +1,30 @@ +From e5aadf1e78c624a8e4147d4b70a7795497a50e73 Mon Sep 17 00:00:00 2001 +From: Niels Baggesen +Date: Mon, 22 May 2023 18:44:36 +0200 +Subject: [PATCH] if-mib/data_access/interface.c: plug a leak with pcre2 + +--- + agent/mibgroup/if-mib/data_access/interface.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/agent/mibgroup/if-mib/data_access/interface.c ++++ b/agent/mibgroup/if-mib/data_access/interface.c +@@ -829,7 +829,7 @@ int netsnmp_access_interface_include(con + { + netsnmp_include_if_list *if_ptr; + #if defined(HAVE_PCRE2_H) +- pcre2_match_data *ndx_match = pcre2_match_data_create(3, NULL); ++ pcre2_match_data *ndx_match; + #elif defined(HAVE_PCRE_H) + int found_ndx[3]; + #endif +@@ -844,6 +844,9 @@ int netsnmp_access_interface_include(con + */ + return TRUE; + ++#if defined(HAVE_PCRE2_H) ++ ndx_match = pcre2_match_data_create(3, NULL); ++#endif + + for (if_ptr = include_list; if_ptr; if_ptr = if_ptr->next) { + #if defined(HAVE_PCRE2_H) diff --git a/net-snmp-ssl/patches/750-ieee802dot11.patch b/net-snmp-ssl/patches/750-ieee802dot11.patch new file mode 100644 index 00000000..2eb598a8 --- /dev/null +++ b/net-snmp-ssl/patches/750-ieee802dot11.patch @@ -0,0 +1,6166 @@ +--- /dev/null ++++ b/agent/mibgroup/ieee802dot11.c +@@ -0,0 +1,4916 @@ ++/**************************************************************************** ++* * ++* File Name: ieee802dot11.c * ++* Used By: * ++* * ++* Operating System: * ++* Purpose: * ++* * ++* Comments: * ++* * ++* Author: Larry Simmons * ++* lsimmons@avantcom.com * ++* www.avantcom.com * ++* * ++* Creation Date: 09/02/03 * ++* * ++* Ver Date Inits Modification * ++* ----- -------- ----- ------------ * ++* 0.0.1 09/02/03 LRS created * ++* 0.0.2 09/24/03 LRS wouldn't build after fresh ./configure * ++****************************************************************************/ ++/**************************************************************************** ++* Includes * ++****************************************************************************/ ++#include ++#include ++#include ++#include "ieee802dot11.h" ++#include "iwlib.h" ++#include "util_funcs/header_generic.h" ++ ++/**************************************************************************** ++* Defines * ++****************************************************************************/ ++#define DISPLAYWIEXT // display wireless ext info ++#define TABLE_SIZE 1 ++//#define MINLOADFREQ 15 // min reload frequency in seconds ++#define MINLOADFREQ 5 // min reload frequency in seconds // for testing ++#define PROC_NET_DEV "/proc/net/dev" ++#define PROC_NET_WIRELESS "/proc/net/wireless" ++ ++#ifndef UCHAR ++ typedef unsigned char UCHAR; ++#endif ++ ++/**************************************************************************** ++* Private Functions * ++****************************************************************************/ ++static void loadTables(); ++static void loadWiExt ( int, char *, struct wireless_info * ); ++static void load80211Structs ( int, char *, struct wireless_info * ); ++static void initStructs(); ++ ++// Wireless Extensions Specific Functions ++static void loadWiExtTo80211Structs ( int, char *, struct wireless_info * ); ++static void displayWiExt ( struct wireless_info ); ++ ++// Linked List Functions ++static void addList ( char *, char *, int ); ++static void initLists(); // initialize all the linked lists ++static void flushLists(); // flush all the linked lists ++static void flushList ( char * ); // flush a single linked list ++ ++// Utility Functions ++static int openSocket ( void ); ++static int mWatt2dbm ( int ); ++static char *htob ( char * ); ++static int hasChanged ( char *, int ); ++ ++/**************************************************************************** ++* Private Variables * ++****************************************************************************/ ++static unsigned long lastLoad = 0; // ET in secs at last table load ++ ++static struct avNode *lastNode, *newNode, *np; ++ ++/**************************************************************************** ++* External Functions * ++****************************************************************************/ ++ ++/**************************************************************************** ++* ieee802dot11_variables_oid: * ++* this is the top level oid that we want to register under. This * ++* is essentially a prefix, with the suffix appearing in the * ++* variable below. * ++****************************************************************************/ ++oid ieee802dot11_variables_oid[] = { 1,2,840,10036 }; ++ ++/**************************************************************************** ++* variable7 ieee802dot11_variables: * ++* this variable defines function callbacks and type return information * ++* for the ieee802dot11 mib section * ++****************************************************************************/ ++struct variable7 ieee802dot11_variables[] = { ++/* magic number , variable type , ro/rw , callback fn , L, oidsuffix */ ++#define DOT11STATIONID 3 ++ { DOT11STATIONID , ASN_OCTET_STR , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,1 } }, ++#define DOT11MEDIUMOCCUPANCYLIMIT 4 ++ { DOT11MEDIUMOCCUPANCYLIMIT, ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,2 } }, ++#define DOT11CFPOLLABLE 5 ++ { DOT11CFPOLLABLE , ASN_INTEGER , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,3 } }, ++#define DOT11CFPPERIOD 6 ++ { DOT11CFPPERIOD , ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,4 } }, ++#define DOT11CFPMAXDURATION 7 ++ { DOT11CFPMAXDURATION , ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,5 } }, ++#define DOT11AUTHENTICATIONRESPONSETIMEOUT 8 ++ { DOT11AUTHENTICATIONRESPONSETIMEOUT, ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,6 } }, ++#define DOT11PRIVACYOPTIONIMPLEMENTED 9 ++ { DOT11PRIVACYOPTIONIMPLEMENTED, ASN_INTEGER , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,7 } }, ++#define DOT11POWERMANAGEMENTMODE 10 ++ { DOT11POWERMANAGEMENTMODE, ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,8 } }, ++#define DOT11DESIREDSSID 11 ++ { DOT11DESIREDSSID , ASN_OCTET_STR , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,9 } }, ++#define DOT11DESIREDBSSTYPE 12 ++ { DOT11DESIREDBSSTYPE , ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,10 } }, ++#define DOT11OPERATIONALRATESET 13 ++ { DOT11OPERATIONALRATESET, ASN_OCTET_STR , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,11 } }, ++#define DOT11BEACONPERIOD 14 ++ { DOT11BEACONPERIOD , ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,12 } }, ++#define DOT11DTIMPERIOD 15 ++ { DOT11DTIMPERIOD , ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,13 } }, ++#define DOT11ASSOCIATIONRESPONSETIMEOUT 16 ++ { DOT11ASSOCIATIONRESPONSETIMEOUT, ASN_INTEGER , RWRITE, var_dot11StationConfigTable, 4, { 1,1,1,14 } }, ++#define DOT11DISASSOCIATEREASON 17 ++ { DOT11DISASSOCIATEREASON, ASN_INTEGER , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,15 } }, ++#define DOT11DISASSOCIATESTATION 18 ++ { DOT11DISASSOCIATESTATION, ASN_OCTET_STR , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,16 } }, ++#define DOT11DEAUTHENTICATEREASON 19 ++ { DOT11DEAUTHENTICATEREASON, ASN_INTEGER , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,17 } }, ++#define DOT11DEAUTHENTICATESTATION 20 ++ { DOT11DEAUTHENTICATESTATION, ASN_OCTET_STR , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,18 } }, ++#define DOT11AUTHENTICATEFAILSTATUS 21 ++ { DOT11AUTHENTICATEFAILSTATUS, ASN_INTEGER , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,19 } }, ++#define DOT11AUTHENTICATEFAILSTATION 22 ++ { DOT11AUTHENTICATEFAILSTATION, ASN_OCTET_STR , RONLY , var_dot11StationConfigTable, 4, { 1,1,1,20 } }, ++ ++#define DOT11AUTHENTICATIONALGORITHM 26 ++ { DOT11AUTHENTICATIONALGORITHM, ASN_INTEGER , RONLY , var_dot11AuthenticationAlgorithmsTable, 4, { 1,2,1,2 } }, ++#define DOT11AUTHENTICATIONALGORITHMSENABLE 27 ++ { DOT11AUTHENTICATIONALGORITHMSENABLE, ASN_INTEGER , RWRITE, var_dot11AuthenticationAlgorithmsTable, 4, { 1,2,1,3 } }, ++ ++#define DOT11WEPDEFAULTKEYVALUE 31 ++ { DOT11WEPDEFAULTKEYVALUE, ASN_OCTET_STR , RWRITE, var_dot11WEPDefaultKeysTable, 4, { 1,3,1,2 } }, ++ ++#define DOT11WEPKEYMAPPINGADDRESS 35 ++ { DOT11WEPKEYMAPPINGADDRESS, ASN_OCTET_STR , RWRITE, var_dot11WEPKeyMappingsTable, 4, { 1,4,1,2 } }, ++#define DOT11WEPKEYMAPPINGWEPON 36 ++ { DOT11WEPKEYMAPPINGWEPON, ASN_INTEGER , RWRITE, var_dot11WEPKeyMappingsTable, 4, { 1,4,1,3 } }, ++#define DOT11WEPKEYMAPPINGVALUE 37 ++ { DOT11WEPKEYMAPPINGVALUE, ASN_OCTET_STR , RWRITE, var_dot11WEPKeyMappingsTable, 4, { 1,4,1,4 } }, ++#define DOT11WEPKEYMAPPINGSTATUS 38 ++ { DOT11WEPKEYMAPPINGSTATUS, ASN_INTEGER , RWRITE, var_dot11WEPKeyMappingsTable, 4, { 1,4,1,5 } }, ++ ++#define DOT11PRIVACYINVOKED 41 ++ { DOT11PRIVACYINVOKED , ASN_INTEGER , RWRITE, var_dot11PrivacyTable, 4, { 1,5,1,1 } }, ++#define DOT11WEPDEFAULTKEYID 42 ++ { DOT11WEPDEFAULTKEYID, ASN_INTEGER , RWRITE, var_dot11PrivacyTable, 4, { 1,5,1,2 } }, ++#define DOT11WEPKEYMAPPINGLENGTH 43 ++ { DOT11WEPKEYMAPPINGLENGTH, ASN_INTEGER , RWRITE, var_dot11PrivacyTable, 4, { 1,5,1,3 } }, ++#define DOT11EXCLUDEUNENCRYPTED 44 ++ { DOT11EXCLUDEUNENCRYPTED, ASN_INTEGER , RWRITE, var_dot11PrivacyTable, 4, { 1,5,1,4 } }, ++#define DOT11WEPICVERRORCOUNT 45 ++ { DOT11WEPICVERRORCOUNT, ASN_COUNTER , RONLY , var_dot11PrivacyTable, 4, { 1,5,1,5 } }, ++#define DOT11WEPEXCLUDEDCOUNT 46 ++ { DOT11WEPEXCLUDEDCOUNT, ASN_COUNTER , RONLY , var_dot11PrivacyTable, 4, { 1,5,1,6 } }, ++ ++#define DOT11MACADDRESS 49 ++ { DOT11MACADDRESS , ASN_OCTET_STR , RONLY , var_dot11OperationTable, 4, { 2,1,1,1 } }, ++#define DOT11RTSTHRESHOLD 50 ++ { DOT11RTSTHRESHOLD , ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,2 } }, ++#define DOT11SHORTRETRYLIMIT 51 ++ { DOT11SHORTRETRYLIMIT, ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,3 } }, ++#define DOT11LONGRETRYLIMIT 52 ++ { DOT11LONGRETRYLIMIT , ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,4 } }, ++#define DOT11FRAGMENTATIONTHRESHOLD 53 ++ { DOT11FRAGMENTATIONTHRESHOLD, ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,5 } }, ++#define DOT11MAXTRANSMITMSDULIFETIME 54 ++ { DOT11MAXTRANSMITMSDULIFETIME, ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,6 } }, ++#define DOT11MAXRECEIVELIFETIME 55 ++ { DOT11MAXRECEIVELIFETIME, ASN_INTEGER , RWRITE, var_dot11OperationTable, 4, { 2,1,1,7 } }, ++#define DOT11MANUFACTURERID 56 ++ { DOT11MANUFACTURERID , ASN_OCTET_STR , RONLY , var_dot11OperationTable, 4, { 2,1,1,8 } }, ++#define DOT11PRODUCTID 57 ++ { DOT11PRODUCTID , ASN_OCTET_STR , RONLY , var_dot11OperationTable, 4, { 2,1,1,9 } }, ++ ++#define DOT11TRANSMITTEDFRAGMENTCOUNT 60 ++ { DOT11TRANSMITTEDFRAGMENTCOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,1 } }, ++#define DOT11MULTICASTTRANSMITTEDFRAMECOUNT 61 ++ { DOT11MULTICASTTRANSMITTEDFRAMECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,2 } }, ++#define DOT11FAILEDCOUNT 62 ++ { DOT11FAILEDCOUNT , ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,3 } }, ++#define DOT11RETRYCOUNT 63 ++ { DOT11RETRYCOUNT , ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,4 } }, ++#define DOT11MULTIPLERETRYCOUNT 64 ++ { DOT11MULTIPLERETRYCOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,5 } }, ++#define DOT11FRAMEDUPLICATECOUNT 65 ++ { DOT11FRAMEDUPLICATECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,6 } }, ++#define DOT11RTSSUCCESSCOUNT 66 ++ { DOT11RTSSUCCESSCOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,7 } }, ++#define DOT11RTSFAILURECOUNT 67 ++ { DOT11RTSFAILURECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,8 } }, ++#define DOT11ACKFAILURECOUNT 68 ++ { DOT11ACKFAILURECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,9 } }, ++#define DOT11RECEIVEDFRAGMENTCOUNT 69 ++ { DOT11RECEIVEDFRAGMENTCOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,10 } }, ++#define DOT11MULTICASTRECEIVEDFRAMECOUNT 70 ++ { DOT11MULTICASTRECEIVEDFRAMECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,11 } }, ++#define DOT11FCSERRORCOUNT 71 ++ { DOT11FCSERRORCOUNT , ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,12 } }, ++#define DOT11TRANSMITTEDFRAMECOUNT 72 ++ { DOT11TRANSMITTEDFRAMECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,13 } }, ++#define DOT11WEPUNDECRYPTABLECOUNT 73 ++ { DOT11WEPUNDECRYPTABLECOUNT, ASN_COUNTER , RONLY , var_dot11CountersTable, 4, { 2,2,1,14 } }, ++ ++#define DOT11ADDRESS 77 ++ { DOT11ADDRESS , ASN_OCTET_STR , RWRITE, var_dot11GroupAddressesTable, 4, { 2,3,1,2 } }, ++#define DOT11GROUPADDRESSESSTATUS 78 ++ { DOT11GROUPADDRESSESSTATUS, ASN_INTEGER , RWRITE, var_dot11GroupAddressesTable, 4, { 2,3,1,3 } }, ++ ++#define DOT11RESOURCETYPEIDNAME 79 ++ { DOT11RESOURCETYPEIDNAME, ASN_OCTET_STR , RONLY , var_ieee802dot11, 3, { 3,1,1 } }, ++#define DOT11MANUFACTUREROUI 82 ++ { DOT11MANUFACTUREROUI, ASN_OCTET_STR , RONLY , var_dot11ResourceInfoTable, 5, { 3,1,2,1,1 } }, ++#define DOT11MANUFACTURERNAME 83 ++ { DOT11MANUFACTURERNAME, ASN_OCTET_STR , RONLY , var_dot11ResourceInfoTable, 5, { 3,1,2,1,2 } }, ++#define DOT11MANUFACTURERPRODUCTNAME 84 ++ { DOT11MANUFACTURERPRODUCTNAME, ASN_OCTET_STR , RONLY , var_dot11ResourceInfoTable, 5, { 3,1,2,1,3 } }, ++#define DOT11MANUFACTURERPRODUCTVERSION 85 ++ { DOT11MANUFACTURERPRODUCTVERSION, ASN_OCTET_STR , RONLY , var_dot11ResourceInfoTable, 5, { 3,1,2,1,4 } }, ++ ++#define DOT11PHYTYPE 88 ++ { DOT11PHYTYPE , ASN_INTEGER , RONLY , var_dot11PhyOperationTable, 4, { 4,1,1,1 } }, ++#define DOT11CURRENTREGDOMAIN 89 ++ { DOT11CURRENTREGDOMAIN, ASN_INTEGER , RWRITE, var_dot11PhyOperationTable, 4, { 4,1,1,2 } }, ++#define DOT11TEMPTYPE 90 ++ { DOT11TEMPTYPE , ASN_INTEGER , RONLY , var_dot11PhyOperationTable, 4, { 4,1,1,3 } }, ++#define DOT11CURRENTTXANTENNA 93 ++ { DOT11CURRENTTXANTENNA, ASN_INTEGER , RWRITE, var_dot11PhyAntennaTable, 4, { 4,2,1,1 } }, ++#define DOT11DIVERSITYSUPPORT 94 ++ { DOT11DIVERSITYSUPPORT, ASN_INTEGER , RONLY , var_dot11PhyAntennaTable, 4, { 4,2,1,2 } }, ++#define DOT11CURRENTRXANTENNA 95 ++ { DOT11CURRENTRXANTENNA, ASN_INTEGER , RWRITE, var_dot11PhyAntennaTable, 4, { 4,2,1,3 } }, ++#define DOT11NUMBERSUPPORTEDPOWERLEVELS 98 ++ { DOT11NUMBERSUPPORTEDPOWERLEVELS, ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,1 } }, ++#define DOT11TXPOWERLEVEL1 99 ++ { DOT11TXPOWERLEVEL1 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,2 } }, ++#define DOT11TXPOWERLEVEL2 100 ++ { DOT11TXPOWERLEVEL2 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,3 } }, ++#define DOT11TXPOWERLEVEL3 101 ++ { DOT11TXPOWERLEVEL3 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,4 } }, ++#define DOT11TXPOWERLEVEL4 102 ++ { DOT11TXPOWERLEVEL4 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,5 } }, ++#define DOT11TXPOWERLEVEL5 103 ++ { DOT11TXPOWERLEVEL5 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,6 } }, ++#define DOT11TXPOWERLEVEL6 104 ++ { DOT11TXPOWERLEVEL6 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,7 } }, ++#define DOT11TXPOWERLEVEL7 105 ++ { DOT11TXPOWERLEVEL7 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,8 } }, ++#define DOT11TXPOWERLEVEL8 106 ++ { DOT11TXPOWERLEVEL8 , ASN_INTEGER , RONLY , var_dot11PhyTxPowerTable, 4, { 4,3,1,9 } }, ++#define DOT11CURRENTTXPOWERLEVEL 107 ++ { DOT11CURRENTTXPOWERLEVEL, ASN_INTEGER , RWRITE, var_dot11PhyTxPowerTable, 4, { 4,3,1,10 } }, ++ ++#define DOT11HOPTIME 110 ++ { DOT11HOPTIME , ASN_INTEGER , RONLY , var_dot11PhyFHSSTable, 4, { 4,4,1,1 } }, ++#define DOT11CURRENTCHANNELNUMBER 111 ++ { DOT11CURRENTCHANNELNUMBER, ASN_INTEGER , RWRITE, var_dot11PhyFHSSTable, 4, { 4,4,1,2 } }, ++#define DOT11MAXDWELLTIME 112 ++ { DOT11MAXDWELLTIME , ASN_INTEGER , RONLY , var_dot11PhyFHSSTable, 4, { 4,4,1,3 } }, ++#define DOT11CURRENTDWELLTIME 113 ++ { DOT11CURRENTDWELLTIME, ASN_INTEGER , RWRITE, var_dot11PhyFHSSTable, 4, { 4,4,1,4 } }, ++#define DOT11CURRENTSET 114 ++ { DOT11CURRENTSET , ASN_INTEGER , RWRITE, var_dot11PhyFHSSTable, 4, { 4,4,1,5 } }, ++#define DOT11CURRENTPATTERN 115 ++ { DOT11CURRENTPATTERN , ASN_INTEGER , RWRITE, var_dot11PhyFHSSTable, 4, { 4,4,1,6 } }, ++#define DOT11CURRENTINDEX 116 ++ { DOT11CURRENTINDEX , ASN_INTEGER , RWRITE, var_dot11PhyFHSSTable, 4, { 4,4,1,7 } }, ++ ++#define DOT11CURRENTCHANNEL 119 ++ { DOT11CURRENTCHANNEL , ASN_INTEGER , RWRITE, var_dot11PhyDSSSTable, 4, { 4,5,1,1 } }, ++#define DOT11CCAMODESUPPORTED 120 ++ { DOT11CCAMODESUPPORTED, ASN_INTEGER , RONLY , var_dot11PhyDSSSTable, 4, { 4,5,1,2 } }, ++#define DOT11CURRENTCCAMODE 121 ++ { DOT11CURRENTCCAMODE , ASN_INTEGER , RWRITE, var_dot11PhyDSSSTable, 4, { 4,5,1,3 } }, ++#define DOT11EDTHRESHOLD 122 ++ { DOT11EDTHRESHOLD , ASN_INTEGER , RWRITE, var_dot11PhyDSSSTable, 4, { 4,5,1,4 } }, ++ ++#define DOT11CCAWATCHDOGTIMERMAX 125 ++ { DOT11CCAWATCHDOGTIMERMAX, ASN_INTEGER , RWRITE, var_dot11PhyIRTable, 4, { 4,6,1,1 } }, ++#define DOT11CCAWATCHDOGCOUNTMAX 126 ++ { DOT11CCAWATCHDOGCOUNTMAX, ASN_INTEGER , RWRITE, var_dot11PhyIRTable, 4, { 4,6,1,2 } }, ++#define DOT11CCAWATCHDOGTIMERMIN 127 ++ { DOT11CCAWATCHDOGTIMERMIN, ASN_INTEGER , RWRITE, var_dot11PhyIRTable, 4, { 4,6,1,3 } }, ++#define DOT11CCAWATCHDOGCOUNTMIN 128 ++ { DOT11CCAWATCHDOGCOUNTMIN, ASN_INTEGER , RWRITE, var_dot11PhyIRTable, 4, { 4,6,1,4 } }, ++ ++#define DOT11REGDOMAINSSUPPORTVALUE 132 ++ { DOT11REGDOMAINSSUPPORTVALUE, ASN_INTEGER , RONLY , var_dot11RegDomainsSupportedTable, 4, { 4,7,1,2 } }, ++ ++#define DOT11SUPPORTEDTXANTENNA 136 ++ { DOT11SUPPORTEDTXANTENNA, ASN_INTEGER , RWRITE, var_dot11AntennasListTable, 4, { 4,8,1,2 } }, ++#define DOT11SUPPORTEDRXANTENNA 137 ++ { DOT11SUPPORTEDRXANTENNA, ASN_INTEGER , RWRITE, var_dot11AntennasListTable, 4, { 4,8,1,3 } }, ++#define DOT11DIVERSITYSELECTIONRX 138 ++ { DOT11DIVERSITYSELECTIONRX, ASN_INTEGER , RWRITE, var_dot11AntennasListTable, 4, { 4,8,1,4 } }, ++ ++#define DOT11SUPPORTEDDATARATESTXVALUE 142 ++ { DOT11SUPPORTEDDATARATESTXVALUE, ASN_INTEGER , RONLY , var_dot11SupportedDataRatesTxTable, 4, { 4,9,1,2 } }, ++ ++#define DOT11SUPPORTEDDATARATESRXVALUE 146 ++ { DOT11SUPPORTEDDATARATESRXVALUE, ASN_INTEGER , RONLY , var_dot11SupportedDataRatesRxTable, 4, { 4,10,1,2 } }, ++}; ++// ( L = length of the oidsuffix ) ++ ++/**************************************************************************** ++* * ++* init_ieee802dot11() - perform any required initialization * ++* * ++****************************************************************************/ ++void init_ieee802dot11 ( void ) { ++ ++ /* register ourselves with the agent to handle our mib tree */ ++ REGISTER_MIB("ieee802dot11", ieee802dot11_variables, variable7, ++ ieee802dot11_variables_oid); ++ ++ initLists(); ++} ++ ++/**************************************************************************** ++* * ++* shutdown_ieee802dot11() - perform any required cleanup @ shutdown * ++* * ++****************************************************************************/ ++void shutdown_ieee802dot11 ( void ) ++{ ++ flushLists(); ++} ++ ++/**************************************************************************** ++* * ++* var_ieee802dot11() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_ieee802dot11 ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method) ++{ ++ loadTables(); ++ ++ if ( header_generic ( vp, name, length, exact,var_len,write_method ) ++ == MATCH_FAILED ) ++ return NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11RESOURCETYPEIDNAME: ++ if ( !haveResourceTypeIDName ) ++ return NULL; ++ *var_len = strlen ( resourceTypeIDName ); ++ return ( UCHAR * ) resourceTypeIDName; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11StationConfigTable() - return a variable value from the table * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11StationConfigTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ static char MACWork[17]; ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &scList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ sc = ( struct scTbl_data * ) np->data; ++ rName[vp->namelen] = sc->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ ++ switch ( vp->magic ) { // found requested OID, now check for requested variable ++ case DOT11STATIONID: ++ if ( sc->haveStationID ) found = TRUE; break; ++ case DOT11MEDIUMOCCUPANCYLIMIT: ++ if ( sc->haveMediumOccupancyLimit ) found = TRUE; break; ++ case DOT11CFPOLLABLE: ++ if ( sc->haveCFPPollable ) found = TRUE; break; ++ case DOT11CFPPERIOD: ++ if ( sc->haveCFPPeriod ) found = TRUE; break; ++ case DOT11CFPMAXDURATION: ++ if ( sc->haveMaxDuration ) found = TRUE; break; ++ case DOT11AUTHENTICATIONRESPONSETIMEOUT: ++ if ( sc->haveAuthenticationResponseTimeOut ) found = TRUE; break; ++ case DOT11PRIVACYOPTIONIMPLEMENTED: ++ if ( sc->havePrivacyOptionImplemented ) found = TRUE; break; ++ case DOT11POWERMANAGEMENTMODE: ++ if ( sc->havePowerManagementMode ) found = TRUE; break; ++ case DOT11DESIREDSSID: ++ if ( sc->haveDesiredSSID ) found = TRUE; break; ++ case DOT11DESIREDBSSTYPE: ++ if ( sc->haveDesiredBSSType ) found = TRUE; break; ++ case DOT11OPERATIONALRATESET: ++ if ( sc->haveOperationalRateSet ) found = TRUE; break; ++ case DOT11BEACONPERIOD: ++ if ( sc->haveBeaconPeriod ) found = TRUE; break; ++ case DOT11DTIMPERIOD: ++ if ( sc->haveDTIMPeriod ) found = TRUE; break; ++ case DOT11ASSOCIATIONRESPONSETIMEOUT: ++ if ( sc->haveAssociationResponseTimeOut ) found = TRUE; break; ++ case DOT11DISASSOCIATEREASON: ++ if ( sc->disAssociationReason ) found = TRUE; break; ++ case DOT11DISASSOCIATESTATION: ++ if ( sc->haveDisAssociationStation ) found = TRUE; break; ++ case DOT11DEAUTHENTICATEREASON: ++ if ( sc->deAuthenticationReason ) found = TRUE; break; ++ case DOT11DEAUTHENTICATESTATION: ++ if ( sc->haveDeAuthenticationStation ) found = TRUE; break; ++ case DOT11AUTHENTICATEFAILSTATUS: ++ if ( sc->authenticateFailStatus ) found = TRUE; break; ++ case DOT11AUTHENTICATEFAILSTATION: ++ if ( sc->haveAuthenticateFailStation ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11STATIONID: ++// *write_method = write_dot11StationID; ++ MACWork[ 0] = sc->stationID [ 0]; ++ MACWork[ 1] = sc->stationID [ 1]; ++ MACWork[ 2] = sc->stationID [ 3]; ++ MACWork[ 3] = sc->stationID [ 4]; ++ MACWork[ 4] = sc->stationID [ 6]; ++ MACWork[ 5] = sc->stationID [ 7]; ++ MACWork[ 6] = sc->stationID [ 9]; ++ MACWork[ 7] = sc->stationID [10]; ++ MACWork[ 8] = sc->stationID [12]; ++ MACWork[ 9] = sc->stationID [13]; ++ MACWork[10] = sc->stationID [15]; ++ MACWork[11] = sc->stationID [16]; ++ MACWork[12] = '\0'; ++ *var_len = 6; ++ return ( UCHAR * ) htob ( MACWork ); ++ ++ case DOT11MEDIUMOCCUPANCYLIMIT: ++// *write_method = write_dot11MediumOccupancyLimit; ++ sc->mediumOccupancyLimit = 5; ++ return ( UCHAR * ) &sc->mediumOccupancyLimit; ++ ++ case DOT11CFPOLLABLE: ++ return ( UCHAR * ) &sc->CFPPollable; ++ ++ case DOT11CFPPERIOD: ++// *write_method = write_dot11CFPPeriod; ++ return ( UCHAR * ) &sc->CFPPeriod; ++ ++ case DOT11CFPMAXDURATION: ++// *write_method = write_dot11CFPMaxDuration; ++ return ( UCHAR * ) &sc->maxDuration; ++ ++ case DOT11AUTHENTICATIONRESPONSETIMEOUT: ++// *write_method = write_dot11AuthenticationResponseTimeOut; ++ return ( UCHAR * ) &sc->authenticationResponseTimeOut; ++ ++ case DOT11PRIVACYOPTIONIMPLEMENTED: ++ return ( UCHAR * ) &sc->privacyOptionImplemented; ++ ++ case DOT11POWERMANAGEMENTMODE: ++// *write_method = write_dot11PowerManagementMode; ++ return ( UCHAR * ) &sc->powerManagementMode; ++ ++ case DOT11DESIREDSSID: ++// *write_method = write_dot11DesiredSSID; ++ *var_len = strlen ( sc->desiredSSID ); ++ return ( UCHAR * ) sc->desiredSSID; ++ ++ case DOT11DESIREDBSSTYPE: ++// *write_method = write_dot11DesiredBSSType; ++ return ( UCHAR * ) &sc->desiredBSSType; ++ ++ case DOT11OPERATIONALRATESET: ++// *write_method = write_dot11OperationalRateSet; ++ *var_len = strlen ( sc->operationalRateSet ); ++ return ( UCHAR * ) sc->operationalRateSet; ++ ++ case DOT11BEACONPERIOD: ++// *write_method = write_dot11BeaconPeriod; ++ return ( UCHAR * ) &sc->beaconPeriod; ++ ++ case DOT11DTIMPERIOD: ++// *write_method = write_dot11DTIMPeriod; ++ return ( UCHAR * ) &sc->DTIMPeriod; ++ ++ case DOT11ASSOCIATIONRESPONSETIMEOUT: ++// *write_method = write_dot11AssociationResponseTimeOut; ++ return ( UCHAR * ) &sc->associationResponseTimeOut; ++ ++ case DOT11DISASSOCIATEREASON: ++ return ( UCHAR * ) &sc->disAssociationReason; ++ ++ case DOT11DISASSOCIATESTATION: ++ MACWork[ 0] = sc->disAssociationStation[ 0]; ++ MACWork[ 1] = sc->disAssociationStation[ 1]; ++ MACWork[ 2] = sc->disAssociationStation[ 3]; ++ MACWork[ 3] = sc->disAssociationStation[ 4]; ++ MACWork[ 4] = sc->disAssociationStation[ 6]; ++ MACWork[ 5] = sc->disAssociationStation[ 7]; ++ MACWork[ 6] = sc->disAssociationStation[ 9]; ++ MACWork[ 7] = sc->disAssociationStation[10]; ++ MACWork[ 8] = sc->disAssociationStation[12]; ++ MACWork[ 9] = sc->disAssociationStation[13]; ++ MACWork[10] = sc->disAssociationStation[15]; ++ MACWork[11] = sc->disAssociationStation[16]; ++ MACWork[12] = '\0'; ++ *var_len = 6; ++ return ( UCHAR * ) htob ( MACWork ); ++ ++ case DOT11DEAUTHENTICATEREASON: ++ return ( UCHAR * ) &sc->deAuthenticationReason; ++ ++ case DOT11DEAUTHENTICATESTATION: ++ MACWork[ 0] = sc->deAuthenticationStation[ 0]; ++ MACWork[ 1] = sc->deAuthenticationStation[ 1]; ++ MACWork[ 2] = sc->deAuthenticationStation[ 3]; ++ MACWork[ 3] = sc->deAuthenticationStation[ 4]; ++ MACWork[ 4] = sc->deAuthenticationStation[ 6]; ++ MACWork[ 5] = sc->deAuthenticationStation[ 7]; ++ MACWork[ 6] = sc->deAuthenticationStation[ 9]; ++ MACWork[ 7] = sc->deAuthenticationStation[10]; ++ MACWork[ 8] = sc->deAuthenticationStation[12]; ++ MACWork[ 9] = sc->deAuthenticationStation[13]; ++ MACWork[10] = sc->deAuthenticationStation[15]; ++ MACWork[11] = sc->deAuthenticationStation[16]; ++ MACWork[12] = '\0'; ++ *var_len = 6; ++ return ( UCHAR * ) htob ( MACWork ); ++ ++ case DOT11AUTHENTICATEFAILSTATUS: ++ return ( UCHAR * ) &sc->authenticateFailStatus; ++ ++ case DOT11AUTHENTICATEFAILSTATION: ++ MACWork[ 0] = sc->authenticateFailStation[ 0]; ++ MACWork[ 1] = sc->authenticateFailStation[ 1]; ++ MACWork[ 2] = sc->authenticateFailStation[ 3]; ++ MACWork[ 3] = sc->authenticateFailStation[ 4]; ++ MACWork[ 4] = sc->authenticateFailStation[ 6]; ++ MACWork[ 5] = sc->authenticateFailStation[ 7]; ++ MACWork[ 6] = sc->authenticateFailStation[ 9]; ++ MACWork[ 7] = sc->authenticateFailStation[10]; ++ MACWork[ 8] = sc->authenticateFailStation[12]; ++ MACWork[ 9] = sc->authenticateFailStation[13]; ++ MACWork[10] = sc->authenticateFailStation[15]; ++ MACWork[11] = sc->authenticateFailStation[16]; ++ MACWork[12] = '\0'; ++ *var_len = 6; ++ return ( UCHAR * ) htob ( MACWork ); ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11AuthenticationAlgorithmsTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11AuthenticationAlgorithmsTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &aaList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ aa = ( struct aaTbl_data * ) np->data; ++ rName[vp->namelen + 0] = aa->ifIndex; ++ rName[vp->namelen + 1] = aa->authenticationAlgorithmsIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11AUTHENTICATIONALGORITHM: ++ if ( aa->haveAuthenticationAlgorithm ) found = TRUE; break; ++ case DOT11AUTHENTICATIONALGORITHMSENABLE: ++ if ( aa->authenticationAlgorithmsEnable ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid )); ++ *length = vp->namelen + 2; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11AUTHENTICATIONALGORITHM: ++ return ( UCHAR * ) &aa->authenticationAlgorithm; ++ ++ case DOT11AUTHENTICATIONALGORITHMSENABLE: ++// *write_method = write_dot11AuthenticationAlgorithmsEnable; ++ return ( UCHAR * ) &aa->authenticationAlgorithmsEnable; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11WEPDefaultKeysTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11WEPDefaultKeysTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &dfList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ df = ( struct dfTbl_data * ) np->data; ++ rName[vp->namelen + 0] = df->ifIndex; ++ rName[vp->namelen + 1] = df->WEPDefaultKeyIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11WEPDEFAULTKEYVALUE: ++ if ( df->haveWEPDefaultKeyValue ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid )); ++ *length = vp->namelen + 2; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11WEPDEFAULTKEYVALUE: ++// *write_method = write_dot11WEPDefaultKeyValue; ++ *var_len = strlen ( df->WEPDefaultKeyValue ); ++ return ( UCHAR * ) df->WEPDefaultKeyValue; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11WEPKeyMappingsTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11WEPKeyMappingsTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method) ++{ ++ static char MACWork[17]; ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &kmList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ km = ( struct kmTbl_data * ) np->data; ++ rName[vp->namelen + 0] = km->ifIndex; ++ rName[vp->namelen + 1] = km->WEPKeyMappingIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11WEPKEYMAPPINGADDRESS: ++ if ( km->haveWEPKeyMappingAddress ) found = TRUE; break; ++ case DOT11WEPKEYMAPPINGWEPON: ++ if ( km->haveWEPKeyMappingWEPOn ) found = TRUE; break; ++ case DOT11WEPKEYMAPPINGVALUE: ++ if ( km->haveWEPKeyMappingValue ) found = TRUE; break; ++ case DOT11WEPKEYMAPPINGSTATUS: ++ if ( km->haveWEPKeyMappingStatus ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid )); ++ *length = vp->namelen + 2; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11WEPKEYMAPPINGADDRESS: ++// *write_method = write_dot11WEPKeyMappingAddress; ++ MACWork[ 0] = km->WEPKeyMappingAddress[ 0]; ++ MACWork[ 1] = km->WEPKeyMappingAddress[ 1]; ++ MACWork[ 2] = km->WEPKeyMappingAddress[ 3]; ++ MACWork[ 3] = km->WEPKeyMappingAddress[ 4]; ++ MACWork[ 4] = km->WEPKeyMappingAddress[ 6]; ++ MACWork[ 5] = km->WEPKeyMappingAddress[ 7]; ++ MACWork[ 6] = km->WEPKeyMappingAddress[ 9]; ++ MACWork[ 7] = km->WEPKeyMappingAddress[10]; ++ MACWork[ 8] = km->WEPKeyMappingAddress[12]; ++ MACWork[ 9] = km->WEPKeyMappingAddress[13]; ++ MACWork[10] = km->WEPKeyMappingAddress[15]; ++ MACWork[11] = km->WEPKeyMappingAddress[16]; ++ MACWork[12] = '\0'; ++ *var_len = 6; ++ return ( UCHAR * ) htob ( MACWork ); ++ ++ case DOT11WEPKEYMAPPINGWEPON: ++// *write_method = write_dot11WEPKeyMappingWEPOn; ++ return ( UCHAR * ) &km->WEPKeyMappingWEPOn; ++ ++ case DOT11WEPKEYMAPPINGVALUE: ++// *write_method = write_dot11WEPKeyMappingValue; ++ *var_len = strlen ( km->WEPKeyMappingValue ); ++ return ( UCHAR * ) km->WEPKeyMappingValue; ++ ++ case DOT11WEPKEYMAPPINGSTATUS: ++// *write_method = write_dot11WEPKeyMappingStatus; ++ return ( UCHAR * ) &km->WEPKeyMappingStatus; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11PrivacyTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11PrivacyTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &prList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ pr = ( struct prTbl_data * ) np->data; ++ rName[vp->namelen] = pr->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11PRIVACYINVOKED: ++ if ( pr->havePrivacyInvoked ) found = TRUE; break; ++ case DOT11WEPDEFAULTKEYID: ++ if ( pr->haveWEPDefaultKeyID ) found = TRUE; break; ++ case DOT11WEPKEYMAPPINGLENGTH: ++ if ( pr->haveWEPKeyMappingLength ) found = TRUE; break; ++ case DOT11EXCLUDEUNENCRYPTED: ++ if ( pr->haveExcludeUnencrypted ) found = TRUE; break; ++ case DOT11WEPICVERRORCOUNT: ++ if ( pr->haveWEPICVErrorCount ) found = TRUE; break; ++ case DOT11WEPEXCLUDEDCOUNT: ++ if ( pr->haveWEPExcludedCount ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11PRIVACYINVOKED: ++// *write_method = write_dot11PrivacyInvoked; ++ return ( UCHAR * ) &pr->privacyInvoked; ++ ++ case DOT11WEPDEFAULTKEYID: ++// *write_method = write_dot11WEPDefaultKeyID; ++ return ( UCHAR * ) &pr->WEPDefaultKeyID; ++ ++ case DOT11WEPKEYMAPPINGLENGTH: ++// *write_method = write_dot11WEPKeyMappingLength; ++ return ( UCHAR * ) &pr->WEPKeyMappingLength; ++ ++ case DOT11EXCLUDEUNENCRYPTED: ++// *write_method = write_dot11ExcludeUnencrypted; ++ return ( UCHAR * ) &pr->excludeUnencrypted; ++ ++ case DOT11WEPICVERRORCOUNT: ++ return ( UCHAR * ) &pr->WEPICVErrorCount; ++ ++ case DOT11WEPEXCLUDEDCOUNT: ++ return ( UCHAR * ) &pr->WEPExcludedCount; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11OperationTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11OperationTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ static char MACWork[17]; ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &opList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ op = ( struct opTbl_data * ) np->data; ++ rName[vp->namelen] = op->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ ++ switch ( vp->magic ) { // found requested OID, now check for requested variable ++ case DOT11MACADDRESS: ++ if ( op->haveMACAddress ) found = TRUE; break; ++ case DOT11RTSTHRESHOLD: ++ if ( op->haveRTSThreshold ) found = TRUE; break; ++ case DOT11SHORTRETRYLIMIT: ++ if ( op->haveShortRetryLimit ) found = TRUE; break; ++ case DOT11LONGRETRYLIMIT: ++ if ( op->haveLongRetryLimit ) found = TRUE; break; ++ case DOT11FRAGMENTATIONTHRESHOLD: ++ if ( op->haveFragmentationThreshold ) found = TRUE; break; ++ case DOT11MAXTRANSMITMSDULIFETIME: ++ if ( op->haveMaxTransmitMSDULifetime ) found = TRUE; break; ++ case DOT11MAXRECEIVELIFETIME: ++ if ( op->haveMaxReceiveLifetime ) found = TRUE; break; ++ case DOT11MANUFACTURERID: ++ if ( op->haveManufacturerID ) found = TRUE; break; ++ case DOT11PRODUCTID: ++ if ( op->haveProductID ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11MACADDRESS: ++ MACWork[ 0] = op->MACAddress[ 0]; ++ MACWork[ 1] = op->MACAddress[ 1]; ++ MACWork[ 2] = op->MACAddress[ 3]; ++ MACWork[ 3] = op->MACAddress[ 4]; ++ MACWork[ 4] = op->MACAddress[ 6]; ++ MACWork[ 5] = op->MACAddress[ 7]; ++ MACWork[ 6] = op->MACAddress[ 9]; ++ MACWork[ 7] = op->MACAddress[10]; ++ MACWork[ 8] = op->MACAddress[12]; ++ MACWork[ 9] = op->MACAddress[13]; ++ MACWork[10] = op->MACAddress[15]; ++ MACWork[11] = op->MACAddress[16]; ++ MACWork[12] = '\0'; ++ *var_len = 6; ++ return ( UCHAR * ) htob ( MACWork ); ++ ++ case DOT11RTSTHRESHOLD: ++// *write_method = write_dot11RTSThreshold; ++ return ( UCHAR * ) &op->RTSThreshold; ++ ++ case DOT11SHORTRETRYLIMIT: ++// *write_method = write_dot11ShortRetryLimit; ++ return ( UCHAR * ) &op->shortRetryLimit; ++ ++ case DOT11LONGRETRYLIMIT: ++// *write_method = write_dot11LongRetryLimit; ++ return ( UCHAR * ) &op->longRetryLimit; ++ ++ case DOT11FRAGMENTATIONTHRESHOLD: ++// *write_method = write_dot11FragmentationThreshold; ++ return ( UCHAR * ) &op->fragmentationThreshold; ++ ++ case DOT11MAXTRANSMITMSDULIFETIME: ++// *write_method = write_dot11MaxTransmitMSDULifetime; ++ return ( UCHAR * ) &op->maxTransmitMSDULifetime; ++ ++ case DOT11MAXRECEIVELIFETIME: ++// *write_method = write_dot11MaxReceiveLifetime; ++ return ( UCHAR * ) &op->maxReceiveLifetime; ++ ++ case DOT11MANUFACTURERID: ++ *var_len = strlen ( op->manufacturerID ); ++ return ( UCHAR * ) op->manufacturerID; ++ ++ case DOT11PRODUCTID: ++ *var_len = strlen ( op->productID ); ++ return ( UCHAR * ) op->productID; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11CountersTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11CountersTable(struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &coList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ co = ( struct coTbl_data * ) np->data; ++ rName[vp->namelen] = co->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11TRANSMITTEDFRAGMENTCOUNT: ++ if ( co->haveTransmittedFragmentCount ) found = TRUE; break; ++ case DOT11MULTICASTTRANSMITTEDFRAMECOUNT: ++ if ( co->haveTransmittedFrameCount ) found = TRUE; break; ++ case DOT11FAILEDCOUNT: ++ if ( co->haveFailedCount ) found = TRUE; break; ++ case DOT11RETRYCOUNT: ++ if ( co->haveRetryCount ) found = TRUE; break; ++ case DOT11MULTIPLERETRYCOUNT: ++ if ( co->haveMultipleRetryCount ) found = TRUE; break; ++ case DOT11FRAMEDUPLICATECOUNT: ++ if ( co->haveFrameDuplicateCount ) found = TRUE; break; ++ case DOT11RTSSUCCESSCOUNT: ++ if ( co->haveRTSSuccessCount ) found = TRUE; break; ++ case DOT11RTSFAILURECOUNT: ++ if ( co->haveRTSFailureCount ) found = TRUE; break; ++ case DOT11ACKFAILURECOUNT: ++ if ( co->haveACKFailureCount ) found = TRUE; break; ++ case DOT11RECEIVEDFRAGMENTCOUNT: ++ if ( co->haveReceivedFragmentCount ) found = TRUE; break; ++ case DOT11MULTICASTRECEIVEDFRAMECOUNT: ++ if ( co->haveMulticastReceivedFrameCount ) found = TRUE; break; ++ case DOT11FCSERRORCOUNT: ++ if ( co->haveFCSErrorCount ) found = TRUE; break; ++ case DOT11TRANSMITTEDFRAMECOUNT: ++ if ( co->haveTransmittedFrameCount ) found = TRUE; break; ++ case DOT11WEPUNDECRYPTABLECOUNT: ++ if ( co->haveWEPUndecryptableCount ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11TRANSMITTEDFRAGMENTCOUNT: return ( UCHAR * ) &co->transmittedFragmentCount; ++ case DOT11MULTICASTTRANSMITTEDFRAMECOUNT: return ( UCHAR * ) &co->transmittedFrameCount; ++ case DOT11FAILEDCOUNT: return ( UCHAR * ) &co->failedCount; ++ case DOT11RETRYCOUNT: return ( UCHAR * ) &co->retryCount; ++ case DOT11MULTIPLERETRYCOUNT: return ( UCHAR * ) &co->multipleRetryCount; ++ case DOT11FRAMEDUPLICATECOUNT: return ( UCHAR * ) &co->frameDuplicateCount; ++ case DOT11RTSSUCCESSCOUNT: return ( UCHAR * ) &co->RTSSuccessCount; ++ case DOT11RTSFAILURECOUNT: return ( UCHAR * ) &co->RTSFailureCount; ++ case DOT11ACKFAILURECOUNT: return ( UCHAR * ) &co->ACKFailureCount; ++ case DOT11RECEIVEDFRAGMENTCOUNT: return ( UCHAR * ) &co->receivedFragmentCount; ++ case DOT11MULTICASTRECEIVEDFRAMECOUNT: return ( UCHAR * ) &co->multicastReceivedFrameCount; ++ case DOT11FCSERRORCOUNT: return ( UCHAR * ) &co->FCSErrorCount; ++ case DOT11TRANSMITTEDFRAMECOUNT: return ( UCHAR * ) &co->transmittedFrameCount; ++ case DOT11WEPUNDECRYPTABLECOUNT: return ( UCHAR * ) &co->WEPUndecryptableCount; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11GroupAddressesTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11GroupAddressesTable(struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method) ++{ ++ static char MACWork[17]; ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &gaList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ ga = ( struct gaTbl_data * ) np->data; ++ rName[vp->namelen + 0] = ga->ifIndex; ++ rName[vp->namelen + 1] = ga->groupAddressesIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11ADDRESS: ++ if ( ga->haveAddress ) found = TRUE; break; ++ case DOT11GROUPADDRESSESSTATUS: ++ if ( ga->haveGroupAddressesStatus ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid )); ++ *length = vp->namelen + 2; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11ADDRESS: ++// *write_method = write_dot11Address; ++ MACWork[ 0] = ga->address[ 0]; ++ MACWork[ 1] = ga->address[ 1]; ++ MACWork[ 2] = ga->address[ 3]; ++ MACWork[ 3] = ga->address[ 4]; ++ MACWork[ 4] = ga->address[ 6]; ++ MACWork[ 5] = ga->address[ 7]; ++ MACWork[ 6] = ga->address[ 9]; ++ MACWork[ 7] = ga->address[10]; ++ MACWork[ 8] = ga->address[12]; ++ MACWork[ 9] = ga->address[13]; ++ MACWork[10] = ga->address[15]; ++ MACWork[11] = ga->address[16]; ++ MACWork[12] = '\0'; ++ *var_len = 6; ++ return ( UCHAR * ) htob ( MACWork ); ++ ++ case DOT11GROUPADDRESSESSTATUS: ++// *write_method = write_dot11GroupAddressesStatus; ++ return ( UCHAR * ) &ga->groupAddressesStatus; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11ResourceInfoTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11ResourceInfoTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &riList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ ri = ( struct riTbl_data * ) np->data; ++ rName[vp->namelen] = ri->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11MANUFACTUREROUI: ++ if ( ri->haveManufacturerOUI ) found = TRUE; break; ++ case DOT11MANUFACTURERNAME: ++ if ( ri->haveManufacturerName ) found = TRUE; break; ++ case DOT11MANUFACTURERPRODUCTNAME: ++ if ( ri->haveManufacturerProductName ) found = TRUE; break; ++ case DOT11MANUFACTURERPRODUCTVERSION: ++ if ( ri->haveManufacturerProductVersion ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11MANUFACTUREROUI: ++ *var_len = strlen ( ri->manufacturerOUI ); ++ return ( UCHAR * ) ri->manufacturerOUI; ++ ++ case DOT11MANUFACTURERNAME: ++ *var_len = strlen ( ri->manufacturerName ); ++ return ( UCHAR * ) ri->manufacturerName; ++ ++ case DOT11MANUFACTURERPRODUCTNAME: ++ *var_len = strlen ( ri->manufacturerProductName ); ++ return ( UCHAR * ) ri->manufacturerProductName; ++ ++ case DOT11MANUFACTURERPRODUCTVERSION: ++ *var_len = strlen ( ri->manufacturerProductVersion ); ++ return ( UCHAR * ) ri->manufacturerProductVersion; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11PhyOperationTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11PhyOperationTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &poList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ po = ( struct poTbl_data * ) np->data; ++ rName[vp->namelen] = po->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11PHYTYPE: ++ if ( po->havePHYType ) found = TRUE; break; ++ case DOT11CURRENTREGDOMAIN: ++ if ( po->haveCurrentRegDomain ) found = TRUE; break; ++ case DOT11TEMPTYPE: ++ if ( po->haveTempType ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11PHYTYPE: ++ return ( UCHAR * ) &po->PHYType; ++ ++ case DOT11CURRENTREGDOMAIN: ++// *write_method = write_dot11CurrentRegDomain; ++ return ( UCHAR * ) &po->currentRegDomain; ++ ++ case DOT11TEMPTYPE: ++ return ( UCHAR * ) &po->tempType; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11PhyAntennaTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11PhyAntennaTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &paList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ pa = ( struct paTbl_data * ) np->data; ++ rName[vp->namelen] = pa->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11CURRENTTXANTENNA: ++ if ( pa->haveCurrentTxAntenna ) found = TRUE; break; ++ case DOT11DIVERSITYSUPPORT: ++ if ( pa->haveDiversitySupport ) found = TRUE; break; ++ case DOT11CURRENTRXANTENNA: ++ if ( pa->haveCurrentRxAntenna ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11CURRENTTXANTENNA: ++// *write_method = write_dot11CurrentTxAntenna; ++ return ( UCHAR * ) &pa->currentTxAntenna; ++ ++ case DOT11DIVERSITYSUPPORT: ++ return ( UCHAR * ) &pa->diversitySupport; ++ ++ case DOT11CURRENTRXANTENNA: ++// *write_method = write_dot11CurrentRxAntenna; ++ return ( UCHAR * ) &pa->currentRxAntenna; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11PhyTxPowerTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11PhyTxPowerTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &ptList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ pt = ( struct ptTbl_data * ) np->data; ++ rName[vp->namelen] = pt->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11NUMBERSUPPORTEDPOWERLEVELS: ++ if ( pt->haveNumberSupportedPowerLevels ) found = TRUE; break; ++ case DOT11TXPOWERLEVEL1: ++ if ( pt->haveTxPowerLevel1 ) found = TRUE; break; ++ case DOT11TXPOWERLEVEL2: ++ if ( pt->haveTxPowerLevel2 ) found = TRUE; break; ++ case DOT11TXPOWERLEVEL3: ++ if ( pt->haveTxPowerLevel3 ) found = TRUE; break; ++ case DOT11TXPOWERLEVEL4: ++ if ( pt->haveTxPowerLevel4 ) found = TRUE; break; ++ case DOT11TXPOWERLEVEL5: ++ if ( pt->haveTxPowerLevel5 ) found = TRUE; break; ++ case DOT11TXPOWERLEVEL6: ++ if ( pt->haveTxPowerLevel6 ) found = TRUE; break; ++ case DOT11TXPOWERLEVEL7: ++ if ( pt->haveTxPowerLevel7 ) found = TRUE; break; ++ case DOT11TXPOWERLEVEL8: ++ if ( pt->haveTxPowerLevel8 ) found = TRUE; break; ++ case DOT11CURRENTTXPOWERLEVEL: ++ if ( pt->currentTxPowerLevel ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11NUMBERSUPPORTEDPOWERLEVELS: ++ return ( UCHAR * ) &pt->numberSupportedPowerLevels; ++ ++ case DOT11TXPOWERLEVEL1: return ( UCHAR * ) &pt->TxPowerLevel1; ++ case DOT11TXPOWERLEVEL2: return ( UCHAR * ) &pt->TxPowerLevel2; ++ case DOT11TXPOWERLEVEL3: return ( UCHAR * ) &pt->TxPowerLevel3; ++ case DOT11TXPOWERLEVEL4: return ( UCHAR * ) &pt->TxPowerLevel4; ++ case DOT11TXPOWERLEVEL5: return ( UCHAR * ) &pt->TxPowerLevel5; ++ case DOT11TXPOWERLEVEL6: return ( UCHAR * ) &pt->TxPowerLevel6; ++ case DOT11TXPOWERLEVEL7: return ( UCHAR * ) &pt->TxPowerLevel7; ++ case DOT11TXPOWERLEVEL8: return ( UCHAR * ) &pt->TxPowerLevel8; ++ ++ case DOT11CURRENTTXPOWERLEVEL: ++// *write_method = write_dot11CurrentTxPowerLevel; ++ return ( UCHAR * ) &pt->currentTxPowerLevel; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11PhyFHSSTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11PhyFHSSTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &pfList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ pf = ( struct pfTbl_data * ) np->data; ++ rName[vp->namelen] = pf->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11HOPTIME: ++ if ( pf->haveHopTime ) found = TRUE; break; ++ case DOT11CURRENTCHANNELNUMBER: ++ if ( pf->haveCurrentChannelNumber ) found = TRUE; break; ++ case DOT11MAXDWELLTIME: ++ if ( pf->haveMaxDwellTime ) found = TRUE; break; ++ case DOT11CURRENTDWELLTIME: ++ if ( pf->haveCurrentDwellTime ) found = TRUE; break; ++ case DOT11CURRENTSET: ++ if ( pf->haveCurrentSet ) found = TRUE; break; ++ case DOT11CURRENTPATTERN: ++ if ( pf->haveCurrentPattern ) found = TRUE; break; ++ case DOT11CURRENTINDEX: ++ if ( pf->haveCurrentIndex ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11HOPTIME: ++ return ( UCHAR * ) &pf->hopTime; ++ ++ case DOT11CURRENTCHANNELNUMBER: ++// *write_method = write_dot11CurrentChannelNumber; ++ return ( UCHAR * ) &pf->currentChannelNumber; ++ ++ case DOT11MAXDWELLTIME: ++ return ( UCHAR * ) &pf->maxDwellTime; ++ ++ case DOT11CURRENTDWELLTIME: ++// *write_method = write_dot11CurrentDwellTime; ++ return ( UCHAR * ) &pf->currentDwellTime; ++ ++ case DOT11CURRENTSET: ++// *write_method = write_dot11CurrentSet; ++ return ( UCHAR * ) &pf->currentSet; ++ ++ case DOT11CURRENTPATTERN: ++// *write_method = write_dot11CurrentPattern; ++ return ( UCHAR * ) &pf->currentPattern; ++ ++ case DOT11CURRENTINDEX: ++// *write_method = write_dot11CurrentIndex; ++ return ( UCHAR * ) &pf->currentIndex; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11PhyDSSSTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11PhyDSSSTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &pdList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ pd = ( struct pdTbl_data * ) np->data; ++ rName[vp->namelen] = pd->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11CURRENTCHANNEL: ++ if ( pd->haveCurrentChannel ) found = TRUE; break; ++ case DOT11CCAMODESUPPORTED: ++ if ( pd->haveCCAModeSupported ) found = TRUE; break; ++ case DOT11CURRENTCCAMODE: ++ if ( pd->haveCurrentCCAMode ) found = TRUE; break; ++ case DOT11EDTHRESHOLD: ++ if ( pd->haveEDThreshold ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11CURRENTCHANNEL: ++// *write_method = write_dot11CurrentChannel; ++ return ( UCHAR * ) &pd->currentChannel; ++ ++ case DOT11CCAMODESUPPORTED: ++ return ( UCHAR * ) &pd->CCAModeSupported; ++ ++ case DOT11CURRENTCCAMODE: ++// *write_method = write_dot11CurrentCCAMode; ++ return ( UCHAR * ) &pd->currentCCAMode; ++ ++ case DOT11EDTHRESHOLD: ++// *write_method = write_dot11EDThreshold; ++ return ( UCHAR * ) &pd->EDThreshold; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11PhyIRTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11PhyIRTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method) ++{ ++ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &piList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ pi = ( struct piTbl_data * ) np->data; ++ rName[vp->namelen] = pi->ifIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 1, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11CCAWATCHDOGTIMERMAX: ++ if ( pi->CCAWatchdogTimerMax ) found = TRUE; break; ++ case DOT11CCAWATCHDOGCOUNTMAX: ++ if ( pi->CCAWatchdogCountMax ) found = TRUE; break; ++ case DOT11CCAWATCHDOGTIMERMIN: ++ if ( pi->CCAWatchdogTimerMin ) found = TRUE; break; ++ case DOT11CCAWATCHDOGCOUNTMIN: ++ if ( pi->CCAWatchdogCountMin ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 1 ) * sizeof ( oid )); ++ *length = vp->namelen + 1; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11CCAWATCHDOGTIMERMAX: ++// *write_method = write_dot11CCAWatchdogTimerMax; ++ return ( UCHAR * ) &pi->CCAWatchdogTimerMax; ++ ++ case DOT11CCAWATCHDOGCOUNTMAX: ++// *write_method = write_dot11CCAWatchdogCountMax; ++ return ( UCHAR * ) &pi->CCAWatchdogCountMax; ++ ++ case DOT11CCAWATCHDOGTIMERMIN: ++// *write_method = write_dot11CCAWatchdogTimerMin; ++ return ( UCHAR * ) &pi->CCAWatchdogTimerMin; ++ ++ case DOT11CCAWATCHDOGCOUNTMIN: ++// *write_method = write_dot11CCAWatchdogCountMin; ++ return ( UCHAR * ) &pi->CCAWatchdogCountMin; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11RegDomainsSupportedTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11RegDomainsSupportedTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &rdList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ rd = ( struct rdTbl_data * ) np->data; ++ rName[vp->namelen + 0] = rd->ifIndex; ++ rName[vp->namelen + 1] = rd->regDomainsSupportIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11REGDOMAINSSUPPORTVALUE: ++ if ( rd->haveRegDomainsSupportValue ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid )); ++ *length = vp->namelen + 2; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11REGDOMAINSSUPPORTVALUE: ++ return ( UCHAR * ) &rd->regDomainsSupportValue; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11AntennasListTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11AntennasListTable(struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &alList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ al = ( struct alTbl_data * ) np->data; ++ rName[vp->namelen + 0] = al->ifIndex; ++ rName[vp->namelen + 1] = al->antennaListIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11SUPPORTEDTXANTENNA: ++ if ( al->haveSupportedTxAntenna ) found = TRUE; break; ++ case DOT11SUPPORTEDRXANTENNA: ++ if ( al->haveSupportedRxAntenna ) found = TRUE; break; ++ case DOT11DIVERSITYSELECTIONRX: ++ if ( al->haveDiversitySelectionRx ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid )); ++ *length = vp->namelen + 2; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11SUPPORTEDTXANTENNA: ++// *write_method = write_dot11SupportedTxAntenna; ++ return ( UCHAR * ) &al->supportedTxAntenna; ++ ++ case DOT11SUPPORTEDRXANTENNA: ++// *write_method = write_dot11SupportedRxAntenna; ++ return ( UCHAR * ) &al->supportedRxAntenna; ++ ++ case DOT11DIVERSITYSELECTIONRX: ++// *write_method = write_dot11DiversitySelectionRx; ++ return ( UCHAR * ) &al->diversitySelectionRx; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11SupportedDataRatesTxTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11SupportedDataRatesTxTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &rtList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ rt = ( struct rtTbl_data * ) np->data; ++ rName[vp->namelen + 0] = rt->ifIndex; ++ rName[vp->namelen + 1] = rt->supportedDataRatesTxIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11SUPPORTEDDATARATESTXVALUE: ++ if ( rt->haveSupportedDataRatesTxValue ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid )); ++ *length = vp->namelen + 2; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11SUPPORTEDDATARATESTXVALUE: ++ return ( UCHAR * ) &rt->supportedDataRatesTxValue; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++* var_dot11SupportedDataRatesRxTable() - * ++* * ++****************************************************************************/ ++unsigned char * ++var_dot11SupportedDataRatesRxTable ( struct variable *vp, ++ oid *name, ++ size_t *length, ++ int exact, ++ size_t *var_len, ++ WriteMethod **write_method ) ++{ ++ int found = FALSE; ++ oid rName [ MAX_OID_LEN ]; // OID to be returned ++ ++ loadTables(); ++ memcpy (( char * ) rName, ( char * ) vp->name, ( int ) vp->namelen * sizeof ( oid )); ++ for ( np = LIST_FIRST ( &rrList ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ rr = ( struct rrTbl_data * ) np->data; ++ rName[vp->namelen + 0] = rr->ifIndex; ++ rName[vp->namelen + 1] = rr->supportedDataRatesRxIndex; ++ if (( exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) == 0 )) || ++ ( !exact && ( snmp_oid_compare ( rName, vp->namelen + 2, name, *length ) > 0 ))) { ++ switch ( vp->magic ) { ++ case DOT11SUPPORTEDDATARATESRXVALUE: ++ if ( rr->haveSupportedDataRatesRxValue ) found = TRUE; break; ++ } ++ } ++ if ( found ) ++ break; ++ } ++ ++ if ( !found ) ++ return NULL; ++ ++ memcpy (( char * ) name, ( char * ) rName, ( vp->namelen + 2 ) * sizeof ( oid )); ++ *length = vp->namelen + 2; ++ *var_len = sizeof ( long ); ++ *write_method = NULL; ++ ++ switch ( vp->magic ) { ++ ++ case DOT11SUPPORTEDDATARATESRXVALUE: ++ return ( UCHAR * ) &rr->supportedDataRatesRxValue; ++ ++ default: ++ ERROR_MSG ( "" ); ++ } ++ ++ return NULL; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11StationID(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static unsigned char string[SPRINT_MAX_LEN]; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_OCTET_STR ) { ++ fprintf ( stderr, "write to dot11StationID not ASN_OCTET_STR\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( string )) { ++ fprintf ( stderr,"write to dot11StationID: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11MediumOccupancyLimit(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11MediumOccupancyLimit not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11MediumOccupancyLimit: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CFPPeriod(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CFPPeriod not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CFPPeriod: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CFPMaxDuration(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CFPMaxDuration not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CFPMaxDuration: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11AuthenticationResponseTimeOut(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11AuthenticationResponseTimeOut not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11AuthenticationResponseTimeOut: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11PowerManagementMode(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11PowerManagementMode not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )) { ++ fprintf ( stderr, "write to dot11PowerManagementMode: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11DesiredSSID(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static unsigned char string[SPRINT_MAX_LEN]; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_OCTET_STR ) { ++ fprintf ( stderr, "write to dot11DesiredSSID not ASN_OCTET_STR\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( string )){ ++ fprintf ( stderr, "write to dot11DesiredSSID: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11DesiredBSSType(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11DesiredBSSType not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11DesiredBSSType: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11OperationalRateSet(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static unsigned char string[SPRINT_MAX_LEN]; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_OCTET_STR ) { ++ fprintf ( stderr, "write to dot11OperationalRateSet not ASN_OCTET_STR\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( string )){ ++ fprintf ( stderr, "write to dot11OperationalRateSet: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11BeaconPeriod(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11BeaconPeriod not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11BeaconPeriod: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11DTIMPeriod(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11DTIMPeriod not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11DTIMPeriod: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11AssociationResponseTimeOut(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11AssociationResponseTimeOut not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )) { ++ fprintf ( stderr,"write to dot11AssociationResponseTimeOut: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11AuthenticationAlgorithmsEnable(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11AuthenticationAlgorithmsEnable not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11AuthenticationAlgorithmsEnable: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11WEPDefaultKeyValue(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static unsigned char string[SPRINT_MAX_LEN]; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_OCTET_STR ) { ++ fprintf ( stderr, "write to dot11WEPDefaultKeyValue not ASN_OCTET_STR\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( string )){ ++ fprintf ( stderr,"write to dot11WEPDefaultKeyValue: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11WEPKeyMappingAddress(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static unsigned char string[SPRINT_MAX_LEN]; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_OCTET_STR ) { ++ fprintf ( stderr, "write to dot11WEPKeyMappingAddress not ASN_OCTET_STR\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( string )) { ++ fprintf ( stderr,"write to dot11WEPKeyMappingAddress: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11WEPKeyMappingWEPOn(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11WEPKeyMappingWEPOn not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11WEPKeyMappingWEPOn: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11WEPKeyMappingValue(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static unsigned char string[SPRINT_MAX_LEN]; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_OCTET_STR ) { ++ fprintf ( stderr, "write to dot11WEPKeyMappingValue not ASN_OCTET_STR\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( string )) { ++ fprintf ( stderr, "write to dot11WEPKeyMappingValue: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11WEPKeyMappingStatus(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11WEPKeyMappingStatus not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11WEPKeyMappingStatus: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11PrivacyInvoked(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11PrivacyInvoked not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11PrivacyInvoked: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11WEPDefaultKeyID(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11WEPDefaultKeyID not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11WEPDefaultKeyID: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11WEPKeyMappingLength(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11WEPKeyMappingLength not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11WEPKeyMappingLength: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11ExcludeUnencrypted(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11ExcludeUnencrypted not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11ExcludeUnencrypted: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11RTSThreshold(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ){ ++ fprintf ( stderr, "write to dot11RTSThreshold not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11RTSThreshold: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11ShortRetryLimit(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11ShortRetryLimit not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11ShortRetryLimit: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11LongRetryLimit(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11LongRetryLimit not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11LongRetryLimit: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11FragmentationThreshold(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11FragmentationThreshold not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11FragmentationThreshold: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11MaxTransmitMSDULifetime(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11MaxTransmitMSDULifetime not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11MaxTransmitMSDULifetime: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11MaxReceiveLifetime(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11MaxReceiveLifetime not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11MaxReceiveLifetime: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11Address(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static unsigned char string[SPRINT_MAX_LEN]; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_OCTET_STR ) { ++ fprintf ( stderr, "write to dot11Address not ASN_OCTET_STR\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( string )){ ++ fprintf ( stderr, "write to dot11Address: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11GroupAddressesStatus(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11GroupAddressesStatus not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11GroupAddressesStatus: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentRegDomain(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentRegDomain not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CurrentRegDomain: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentTxAntenna(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentTxAntenna not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CurrentTxAntenna: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentRxAntenna(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentRxAntenna not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11CurrentRxAntenna: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentTxPowerLevel(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentTxPowerLevel not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CurrentTxPowerLevel: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentChannelNumber(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentChannelNumber not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11CurrentChannelNumber: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentDwellTime(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentDwellTime not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CurrentDwellTime: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentSet(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentSet not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CurrentSet: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentPattern(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentPattern not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CurrentPattern: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentIndex(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentIndex not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CurrentIndex: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentChannel(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentChannel not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CurrentChannel: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CurrentCCAMode(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CurrentCCAMode not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11CurrentCCAMode: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11EDThreshold(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11EDThreshold not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11EDThreshold: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CCAWatchdogTimerMax(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CCAWatchdogTimerMax not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CCAWatchdogTimerMax: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CCAWatchdogCountMax(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CCAWatchdogCountMax not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CCAWatchdogCountMax: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CCAWatchdogTimerMin(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CCAWatchdogTimerMin not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CCAWatchdogTimerMin: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11CCAWatchdogCountMin(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11CCAWatchdogCountMin not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11CCAWatchdogCountMin: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11SupportedTxAntenna(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11SupportedTxAntenna not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11SupportedTxAntenna: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11SupportedRxAntenna(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11SupportedRxAntenna not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr,"write to dot11SupportedRxAntenna: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++int ++write_dot11DiversitySelectionRx(int action, ++ u_char *var_val, ++ u_char var_val_type, ++ size_t var_val_len, ++ u_char *statP, ++ oid *name, ++ size_t name_len) ++{ ++ static long *long_ret; ++ int size; ++ ++ switch ( action ) { ++ ++ case RESERVE1: ++ if ( var_val_type != ASN_INTEGER ) { ++ fprintf ( stderr, "write to dot11DiversitySelectionRx not ASN_INTEGER\n" ); ++ return SNMP_ERR_WRONGTYPE; ++ } ++ if ( var_val_len > sizeof ( long_ret )){ ++ fprintf ( stderr, "write to dot11DiversitySelectionRx: bad length\n" ); ++ return SNMP_ERR_WRONGLENGTH; ++ } ++ break; ++ ++ case RESERVE2: ++ case FREE: ++ case ACTION: ++ case UNDO: ++ break; ++ ++ case COMMIT: ++ break; ++ } ++ ++ return SNMP_ERR_NOERROR; ++} ++ ++/**************************************************************************** ++* * ++* loadTables() - Load the Tables * ++* * ++****************************************************************************/ ++static void loadTables() ++{ ++ int skfd; // generic raw socket desc ++ struct iwreq wrq; // ioctl request structure ++ struct ifreq ifr; ++ struct timeval et; // elapsed time ++ struct wireless_info info; // workarea for wireless ioctl information ++ FILE *fp; ++ char bfr[1024], ifName[1024]; ++ char *s, *t; ++ ++ gettimeofday ( &et, ( struct timezone * ) 0 ); // get time-of-day ++ if ( et.tv_sec < lastLoad + MINLOADFREQ ) // only reload so often ++ return; ++ lastLoad = et.tv_sec; ++ ++ skfd = openSocket(); // open socket ++ if ( skfd < 0 ) { ++ syslog ( LOG_ERR, "SNMP ieee802dot11.loadTables() - %s\n", "socket open failure" ); ++ return; ++ } ++ ++ flushLists(); ++ ++ // find interfaces in /proc/net/dev and find the wireless interfaces ++ fp = fopen ( PROC_NET_DEV, "r" ); ++ if ( fp ) { ++ while ( fgets ( bfr, sizeof ( bfr ), fp )) { ++ if ( strstr ( bfr, ":" )) { ++ s = bfr; t = ifName; ++ while ( isspace ( *s )) // discard white space ++ *s++; ++ while ( *s != ':' ) // get interface name ++ *t++ = *s++; ++ *t = '\0'; ++ ++ // verify as a wireless device ++ memset (( char * ) &info, 0, sizeof ( struct wireless_info )); ++ strncpy ( wrq.ifr_name, ifName, IFNAMSIZ ); ++ if ( ioctl ( skfd, SIOCGIWNAME, &wrq ) >= 0 ) { ++ printf ( "%s ifName: %s\n", "loadTables() -", ifName ); ++ initStructs(); ++ loadWiExt( skfd, ifName, &info ); ++ displayWiExt ( info ); ++ load80211Structs ( skfd, ifName, &info ); ++ } ++ } ++ } ++ fclose ( fp ); ++ } ++ ++ close ( skfd ); ++} ++ ++/**************************************************************************** ++* * ++* load80211Structs() - load the 802.11 structures * ++* * ++****************************************************************************/ ++static void ++load80211Structs ( int skfd, char *ifName, struct wireless_info *wi ) ++{ ++ int rc, ifIndex = 0; ++ struct ifreq ifr; ++ char MACAddress [ MACADDR_LEN + 1 ]; ++ ++ strcpy ( ifr.ifr_name, ifName ); ++ rc = ioctl ( skfd, SIOCGIFHWADDR, &ifr ); ++ if ( rc >= 0 ) { ++ ++ sprintf ( MACAddress, "%02X:%02X:%02X:%02X:%02X:%02X", ++ ( UCHAR ) ifr.ifr_hwaddr.sa_data[0], ( UCHAR ) ifr.ifr_hwaddr.sa_data[1], ++ ( UCHAR ) ifr.ifr_hwaddr.sa_data[2], ( UCHAR ) ifr.ifr_hwaddr.sa_data[3], ++ ( UCHAR ) ifr.ifr_hwaddr.sa_data[4], ( UCHAR ) ifr.ifr_hwaddr.sa_data[5] ); ++ ++ nSc.haveStationID = TRUE; ++ strcpy ( nSc.stationID, MACAddress ); ++ nOp.haveMACAddress = TRUE; ++ strcpy ( nOp.MACAddress, MACAddress ); ++ nRi.haveManufacturerOUI = TRUE; ++ strncpy ( nRi.manufacturerOUI, MACAddress, MAN_OUI_LEN ); ++ ++ ifIndex = if_nametoindex ( ifName ); ++ if ( !ifIndex ) { ++ syslog ( LOG_ERR, "SNMP %s - %s %s\n", ++ "ieee802dot11.load80211Structs()", ifName, "has no ifIndex" ); ++ return; ++ } ++ ++ loadWiExtTo80211Structs ( ifIndex, ifName, wi ); ++ ++ if ( hasChanged (( char * ) &nSc, sizeof ( nSc ))) { ++ nSc.ifIndex = ifIndex; ++ sprintf ( nSc.UID, "%04ld", nSc.ifIndex ); ++ strcpy ( nSc.ifName, ifName ); ++ addList (( char * ) &scList, ( char * ) &nSc, sizeof ( nSc )); ++ } ++ ++ if ( hasChanged (( char * ) &nPr, sizeof ( nPr ))) { ++ nPr.ifIndex = ifIndex; ++ sprintf ( nPr.UID, "%04ld", nPr.ifIndex ); ++ strcpy ( nPr.ifName, ifName ); ++ addList (( char * ) &prList, ( char * ) &nPr, sizeof ( nPr )); ++ } ++ ++ if ( hasChanged (( char * ) &nOp, sizeof ( nOp ))) { ++ nOp.ifIndex = ifIndex; ++ sprintf ( nOp.UID, "%04ld", nOp.ifIndex ); ++ strcpy ( nOp.ifName, ifName ); ++ addList (( char * ) &opList, ( char * ) &nOp, sizeof ( nOp )); ++ } ++ ++ if ( hasChanged (( char * ) &nCo, sizeof ( nCo ))) { ++ nCo.ifIndex = ifIndex; ++ sprintf ( nCo.UID, "%04ld", nCo.ifIndex ); ++ strcpy ( nCo.ifName, ifName ); ++ addList (( char * ) &coList, ( char * ) &nCo, sizeof ( nCo )); ++ } ++ ++ if ( hasChanged (( char * ) &nRi, sizeof ( nRi ))) { ++ nRi.ifIndex = ifIndex; ++ sprintf ( nRi.UID, "%04ld", nRi.ifIndex ); ++ strcpy ( nRi.ifName, ifName ); ++ addList (( char * ) &riList, ( char * ) &nRi, sizeof ( nRi )); ++ } ++ ++ if ( hasChanged (( char * ) &nPo, sizeof ( nPo ))) { ++ nPo.ifIndex = ifIndex; ++ sprintf ( nPo.UID, "%04ld", nPo.ifIndex ); ++ strcpy ( nPo.ifName, ifName ); ++ addList (( char * ) &poList, ( char * ) &nPo, sizeof ( nPo )); ++ } ++ ++ if ( hasChanged (( char * ) &nPa, sizeof ( nPa ))) { ++ nPa.ifIndex = ifIndex; ++ sprintf ( nPa.UID, "%04ld", nPa.ifIndex ); ++ strcpy ( nPa.ifName, ifName ); ++ addList (( char * ) &paList, ( char * ) &nPa, sizeof ( nPa )); ++ } ++ ++ if ( hasChanged (( char * ) &nPt, sizeof ( nPt ))) { ++ nPt.ifIndex = ifIndex; ++ sprintf ( nPt.UID, "%04ld", nPt.ifIndex ); ++ strcpy ( nPt.ifName, ifName ); ++ addList (( char * ) &ptList, ( char * ) &nPt, sizeof ( nPt )); ++ } ++ ++ if ( hasChanged (( char * ) &nPf, sizeof ( nPf ))) { ++ nPf.ifIndex = ifIndex; ++ sprintf ( nPf.UID, "%04ld", nPf.ifIndex ); ++ strcpy ( nPf.ifName, ifName ); ++ addList (( char * ) &pfList, ( char * ) &nPf, sizeof ( nPf )); ++ } ++ ++ if ( hasChanged (( char * ) &nPd, sizeof ( nPd ))) { ++ nPd.ifIndex = ifIndex; ++ sprintf ( nPd.UID, "%04ld", nPd.ifIndex ); ++ strcpy ( nPd.ifName, ifName ); ++ addList (( char * ) &pdList, ( char * ) &nPd, sizeof ( nPd )); ++ } ++ ++ if ( hasChanged (( char * ) &nPi, sizeof ( nPi ))) { ++ nPi.ifIndex = ifIndex; ++ sprintf ( nPi.UID, "%04ld", nPi.ifIndex ); ++ strcpy ( nPi.ifName, ifName ); ++ addList (( char * ) &piList, ( char * ) &nPi, sizeof ( nPi )); ++ } ++ } ++ ++//printf ( "%s - ifIndex: %ld ifName: %s UID: %s\n", ++// "load80211Structs() - HASCHANGED", ifIndex, ifName, nSc.UID ); ++} ++ ++/**************************************************************************** ++* * ++* initStructs() - initialize structures * ++* * ++****************************************************************************/ ++static void initStructs() ++{ ++ int i; ++ ++ // 802.11 MIB Stuctures ++ memset (( char * ) &nSc, 0, sizeof ( nSc )); memset (( char * ) &nAa, 0, sizeof ( nAa )); ++ memset (( char * ) &nDf, 0, sizeof ( nDf )); memset (( char * ) &nKm, 0, sizeof ( nKm )); ++ memset (( char * ) &nPr, 0, sizeof ( nPr )); memset (( char * ) &nOp, 0, sizeof ( nOp )); ++ memset (( char * ) &nCo, 0, sizeof ( nCo )); memset (( char * ) &nGa, 0, sizeof ( nGa )); ++ memset (( char * ) &nRi, 0, sizeof ( nRi )); memset (( char * ) &nPo, 0, sizeof ( nPo )); ++ memset (( char * ) &nPa, 0, sizeof ( nPa )); memset (( char * ) &nPt, 0, sizeof ( nPt )); ++ memset (( char * ) &nPf, 0, sizeof ( nPf )); memset (( char * ) &nPd, 0, sizeof ( nPd )); ++ memset (( char * ) &nPi, 0, sizeof ( nPi )); memset (( char * ) &nRd, 0, sizeof ( nRd )); ++ memset (( char * ) &nAl, 0, sizeof ( nAl )); memset (( char * ) &nRt, 0, sizeof ( nRt )); ++ memset (( char * ) &nRr, 0, sizeof ( nRr )); ++ ++ // Wireless Extensions ++ wepCurrentKey = 0; ++ haveWepCurrentKey = FALSE; ++ for ( i = 0; i < MAX_WEP_KEYS; i++ ) { ++ wep[i].len = 0; ++ wep[i].key[0] = '\0'; ++ wep[i].haveKey = FALSE; ++ } ++} ++ ++/**************************************************************************** ++* * ++* Wireless Extensions Specific Functions * ++* * ++****************************************************************************/ ++/**************************************************************************** ++* * ++* loadWiExtTo80211Structs() - load wireless extensions to 802.11 structures * ++* * ++****************************************************************************/ ++static void ++loadWiExtTo80211Structs ( int ifIndex, char *ifName, struct wireless_info *wi ) ++{ ++ int i, j = 0; ++ ++ // dot11Smt Group ++ // dot11StationConfigTable ++ nSc.havePrivacyOptionImplemented = TRUE; ++ nSc.privacyOptionImplemented = 1; // assume we support WEP ++ ++ if ( wi->has_power ) { ++ nSc.havePowerManagementMode = TRUE; ++ nSc.powerManagementMode = 1; // assume power is active ++ if ( !wi->power.disabled && ++ wi->power.flags & IW_POWER_MIN ) ++ nSc.powerManagementMode = 2; // power save mode ++ } ++ ++ if ( wi->has_essid && strlen ( wi->essid )) { ++ nSc.haveDesiredSSID = TRUE; ++ strcpy ( nSc.desiredSSID, wi->essid ); ++ } ++ ++ if ( wi->has_mode ) { ++ nSc.haveDesiredBSSType = TRUE; ++ if ( wi->mode == IW_MODE_ADHOC ) ++ nSc.desiredBSSType = 2; // independent ++ else if ( wi->has_ap_addr ) ++ nSc.desiredBSSType = 1; // infrastructure ++ else ++ nSc.desiredBSSType = 3; // any ++ } ++ ++ if ( wi->has_range ) { ++ for ( i = 0; i < wi->range.num_bitrates && j < 126; i++ ) { ++ nSc.haveOperationalRateSet = TRUE; ++ nSc.operationalRateSet[j++] = ( char ) ( wi->range.bitrate[i] / 500000L ); ++ } ++ } ++ ++ // dot11AuthenticationAlgorithmsTable ++ nAa.haveAuthenticationAlgorithm = TRUE; // it's a rule to always have ++ nAa.haveAuthenticationAlgorithmsEnable = TRUE; // 'open' supported ++ nAa.ifIndex = ifIndex; ++ nAa.authenticationAlgorithmsIndex = 1; // index number one ++ nAa.authenticationAlgorithm = 1; // 1 => open key ++ sprintf ( nAa.UID, "%04ld%04ld", nAa.ifIndex, nAa.authenticationAlgorithmsIndex ); ++ nAa.authenticationAlgorithmsEnable = 1; // enabled by default ++ if ( ( wi->has_key ) && ++ ( wi->key_size != 0 ) && ++ !( wi->key_flags & IW_ENCODE_DISABLED )) ++ nAa.authenticationAlgorithmsEnable = 2; ++ addList (( char * ) &aaList, ( char * ) &nAa, sizeof ( nAa )); ++ ++ nAa.haveAuthenticationAlgorithm = TRUE; // I'm gonna assume we always support WEP ++ nAa.haveAuthenticationAlgorithmsEnable = TRUE; ++ nAa.ifIndex = ifIndex; ++ nAa.authenticationAlgorithmsIndex = 2; // index number 2 ++ nAa.authenticationAlgorithm = 2; // 2 => shared key ++ sprintf ( nAa.UID, "%04ld%04ld", nAa.ifIndex, nAa.authenticationAlgorithmsIndex ); ++ nAa.authenticationAlgorithmsEnable = 2; ++ if ( ( wi->has_key ) && ++ ( wi->key_size != 0 ) && ++ !( wi->key_flags & IW_ENCODE_DISABLED )) ++ nAa.authenticationAlgorithmsEnable = 1; // disabled by default ++ addList (( char * ) &aaList, ( char * ) &nAa, sizeof ( nAa )); ++ ++ //dot11WEPDefaultKeysTable ++ if ( wi->has_range ) { ++ for ( i = 0; i < MAX_WEP_KEYS; i++ ) { ++ nDf.haveWEPDefaultKeyValue = TRUE; ++ nDf.ifIndex = ifIndex; ++ nDf.WEPDefaultKeyIndex = i + 1; // index number ++ sprintf ( nDf.UID, "%04ld%04ld", nDf.ifIndex, nDf.WEPDefaultKeyIndex ); ++ if ( wep[i].haveKey ) ++ strcpy ( nDf.WEPDefaultKeyValue, "*****" ); ++ else ++ nDf.WEPDefaultKeyValue[0] = '\0'; ++ addList (( char * ) &dfList, ( char * ) &nDf, sizeof ( nDf )); ++ } ++ } ++ ++ // dot11PrivacyTable ++ nPr.havePrivacyInvoked = TRUE; ++ nPr.privacyInvoked = 2; // 2 => FALSE ++ nPr.haveWEPDefaultKeyID = TRUE; ++ nPr.WEPDefaultKeyID = 0; ++ nPr.haveExcludeUnencrypted = TRUE; ++ nPr.excludeUnencrypted = 2; // 2 => FALSE ++ if ( wi->has_range ) { ++ if ( ( wi->key_size != 0 ) && ++ !( wi->key_flags & IW_ENCODE_DISABLED )) { ++ nPr.privacyInvoked = 1; ++ if ( wi->key_flags & IW_ENCODE_RESTRICTED ) ++ nPr.excludeUnencrypted = 1; ++ nPr.WEPDefaultKeyID = wepCurrentKey; ++ } ++ } ++ ++ // dot11Mac Group ++ // dot11OperationTable ++ if ( wi->has_range ) { ++ nOp.haveRTSThreshold = TRUE; ++ nOp.RTSThreshold = wi->range.max_rts; ++ } ++ ++ if ( wi->has_frag && wi->frag.value ) { ++ nOp.haveFragmentationThreshold = TRUE; ++ nOp.fragmentationThreshold = wi->frag.value; ++ } ++ ++ // dot11Phy Group ++ // dot11PhyOperationTable ++ if ( strstr ( wi->name, "IEEE 802.11-FS" )) nPo.PHYType = 1; // So what if I ++ if ( strstr ( wi->name, "IEEE 802.11-DS" )) nPo.PHYType = 2; // made up a couple? ++ if ( strstr ( wi->name, "IEEE 802.11-IR" )) nPo.PHYType = 3; ++ if ( strstr ( wi->name, "IEEE 802.11-OFDM" )) nPo.PHYType = 4; // 802.11a ++ if ( strstr ( wi->name, "IEEE 802.11-OFDM/DS" )) nPo.PHYType = 5; // 802.11g ++ if ( strstr ( wi->name, "IEEE 802.11-TURBO" )) nPo.PHYType = 6; // Atheros TURBO mode ++ if ( nPo.PHYType ) nPo.havePHYType = TRUE; ++ ++ // dot11PhyDSSSTable ++ if ( wi->has_range ) { // && wi->freq <= ( double ) 2483000000 ) { // DSSS frequencies only ++ for ( i = 0; i < wi->range.num_frequency; i++ ) { ++ if ((( double ) ( wi->range.freq[i].e * 10 ) * ( double ) wi->range.freq[i].m ) == wi->freq ) { ++ nPd.haveCurrentChannel = TRUE; ++ nPd.currentChannel = wi->range.freq[i].i; ++ } ++ } ++ } ++ ++ // dot11SupportedDataRatesTxTable ++ if ( wi->has_range ) { ++ for ( i = 0; i < wi->range.num_bitrates; i++ ) { ++ nRt.ifIndex = ifIndex; ++ nRt.supportedDataRatesTxIndex = i + 1; ++ nRt.supportedDataRatesTxValue = wi->range.bitrate[i] / 500000L; ++ nRt.haveSupportedDataRatesTxValue = TRUE; ++ sprintf ( nRt.UID, "%04ld%04ld", nRt.ifIndex, nRt.supportedDataRatesTxIndex ); ++ strcpy ( nRt.ifName, ifName ); ++ addList (( char * ) &rtList, ( char * ) &nRt, sizeof ( nRt )); ++ } ++ } ++ ++ // dot11SupportedDataRatesRxTable ++ if ( wi->has_range ) { ++ for ( i = 0; i < wi->range.num_bitrates; i++ ) { ++ nRr.ifIndex = ifIndex; ++ nRr.supportedDataRatesRxIndex = i + 1; ++ nRr.supportedDataRatesRxValue = wi->range.bitrate[i] / 500000L; ++ nRr.haveSupportedDataRatesRxValue = TRUE; ++ sprintf ( nRr.UID, "%04ld%04ld", nRr.ifIndex, nRr.supportedDataRatesRxIndex ); ++ strcpy ( nRr.ifName, ifName ); ++ addList (( char * ) &rrList, ( char * ) &nRr, sizeof ( nRr )); ++ } ++ } ++ ++//printf ( "%s max_encoding_tokens: %d\n", ++// "loadWiExtTo80211Structs() - ", wi->range.max_encoding_tokens ); ++} ++ ++/**************************************************************************** ++* * ++* loadWiExt() - load wireless extensions structures; * ++* use ioctl calls and read /proc/net/wireless * ++* * ++****************************************************************************/ ++static void loadWiExt ( int skfd, char *ifname, struct wireless_info *wi ) ++{ ++ struct iwreq wrq; // ioctl request structure ++ FILE *fp; ++ char bfr[1024]; ++ char buffer[sizeof ( iwrange ) * 2]; /* Large enough */ ++ char *s, *t; ++ int i, j; ++ ++ strncpy ( wrq.ifr_name, ifname, IFNAMSIZ ); ++ ++ /* Get wireless name */ ++ if ( ioctl ( skfd, SIOCGIWNAME, &wrq ) >= 0 ) { ++ strncpy ( wi->name, wrq.u.name, IFNAMSIZ ); ++ wi->name[IFNAMSIZ] = '\0'; ++ } ++ ++ /* Get ranges */ // NOTE: some version checking in iwlib.c ++ memset ( buffer, 0, sizeof ( buffer )); ++ wrq.u.data.pointer = ( caddr_t ) &buffer; ++ wrq.u.data.length = sizeof ( buffer ); ++ wrq.u.data.flags = 0; ++ if ( ioctl ( skfd, SIOCGIWRANGE, &wrq ) >= 0 ) { ++ memcpy (( char * ) &wi->range, buffer, sizeof ( iwrange )); ++ wi->has_range = 1; ++ } ++ ++ /* Get network ID */ ++ if ( ioctl ( skfd, SIOCGIWNWID, &wrq ) >= 0 ) { ++ memcpy ( &wi->nwid, &wrq.u.nwid, sizeof ( iwparam )); ++ wi->has_nwid = 1; ++ } ++ ++ /* Get frequency / channel */ // THIS NUMBER LOOKS FUNNY ++ if ( ioctl ( skfd, SIOCGIWFREQ, &wrq ) >= 0 ) { ++ wi->has_freq = 1; ++ wi->freq = (( double ) wrq.u.freq.m ) * pow ( 10, wrq.u.freq.e ); ++ } ++ ++ /* Get sensitivity */ ++ if ( ioctl ( skfd, SIOCGIWSENS, &wrq ) >= 0 ) { ++ wi->has_sens = 1; ++ memcpy ( &wi->sens, &wrq.u.sens, sizeof ( iwparam )); ++ } ++ ++ /* Get encryption information */ ++ wrq.u.data.pointer = ( caddr_t ) &wi->key; ++ wrq.u.data.length = IW_ENCODING_TOKEN_MAX; ++ wrq.u.data.flags = 0; ++ if ( ioctl ( skfd, SIOCGIWENCODE, &wrq ) >= 0 ) { ++ wi->has_key = 1; ++ wi->key_size = wrq.u.data.length; ++ wi->key_flags = wrq.u.data.flags; ++ wepCurrentKey = wrq.u.data.flags & IW_ENCODE_INDEX; ++ } ++ ++ for ( i = 0; i < wi->range.max_encoding_tokens; i++ ) { ++ wrq.u.data.pointer = ( caddr_t ) &wi->key; ++ wrq.u.data.length = IW_ENCODING_TOKEN_MAX; ++ wrq.u.data.flags = i; ++ if ( ioctl ( skfd, SIOCGIWENCODE, &wrq ) >= 0 ) { ++ if ( ( wrq.u.data.length != 0 ) && ++ !( wrq.u.data.flags & IW_ENCODE_DISABLED )) { ++ wep[i].len = wrq.u.data.length; ++ wep[i].haveKey = TRUE; ++ t = wep[i].key; ++ for ( j = 0; j < wrq.u.data.length; j++ ) { ++ if (( j & 0x1 ) == 0 && j != 0 ) ++ strcpy ( t++, "-"); ++ sprintf ( t, "%.2X", wi->key[j] ); ++ t += 2; ++ } ++ t = '\0'; ++ } ++ } ++ } ++ ++ /* Get ESSID */ ++ wrq.u.essid.pointer = ( caddr_t ) &wi->essid; ++ wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1; ++ wrq.u.essid.flags = 0; ++ if ( ioctl ( skfd, SIOCGIWESSID, &wrq ) >= 0 ) { ++ wi->has_essid = 1; ++ wi->essid_on = wrq.u.data.flags; ++ } ++ ++ /* Get AP address */ ++ if ( ioctl ( skfd, SIOCGIWAP, &wrq ) >= 0 ) { ++ wi->has_ap_addr = 1; ++ memcpy ( &wi->ap_addr, &wrq.u.ap_addr, sizeof ( sockaddr )); ++ } ++ ++ /* Get NickName */ ++ wrq.u.essid.pointer = ( caddr_t ) &wi->nickname; ++ wrq.u.essid.length = IW_ESSID_MAX_SIZE + 1; ++ wrq.u.essid.flags = 0; ++ if ( ioctl ( skfd, SIOCGIWNICKN, &wrq ) >= 0 ) { ++ if ( wrq.u.data.length > 1 ) ++ wi->has_nickname = 1; ++ } ++ ++ /* Get bit rate */ ++ if ( ioctl ( skfd, SIOCGIWRATE, &wrq ) >= 0 ) { ++ wi->has_bitrate = 1; ++ memcpy ( &wi->bitrate, &wrq.u.bitrate, sizeof ( iwparam )); ++ } ++ ++ /* Get RTS threshold */ ++ if ( ioctl ( skfd, SIOCGIWRTS, &wrq ) >= 0 ) { ++ wi->has_rts = 1; ++ memcpy ( &wi->rts, &wrq.u.rts, sizeof ( iwparam )); ++ } ++ ++ /* Get fragmentation threshold */ ++ if ( ioctl ( skfd, SIOCGIWFRAG, &wrq ) >= 0 ) { ++ wi->has_frag = 1; ++ memcpy ( &wi->frag, &wrq.u.frag, sizeof ( iwparam )); ++ } ++ ++ /* Get operation mode */ ++ if ( ioctl ( skfd, SIOCGIWMODE, &wrq ) >= 0 ) { ++ wi->mode = wrq.u.mode; ++ if ( wi->mode < IW_NUM_OPER_MODE && wi->mode >= 0 ) ++ wi->has_mode = 1; ++ } ++ ++ /* Get Power Management settings */ // #if WIRELESS_EXT > 9 ++ wrq.u.power.flags = 0; ++ if ( ioctl ( skfd, SIOCGIWPOWER, &wrq ) >= 0 ) { ++ wi->has_power = 1; ++ memcpy ( &wi->power, &wrq.u.power, sizeof ( iwparam )); ++ } ++ ++ /* Get retry limit/lifetime */ // #if WIRELESS_EXT > 10 ++ if ( ioctl ( skfd, SIOCGIWRETRY, &wrq ) >= 0 ) { ++ wi->has_retry = 1; ++ memcpy ( &wi->retry, &wrq.u.retry, sizeof ( iwparam )); ++ } ++ ++ /* Get stats */ // #if WIRELESS_EXT > 11 ++ wrq.u.data.pointer = ( caddr_t ) &wi->stats; ++ wrq.u.data.length = 0; ++ wrq.u.data.flags = 1; /* Clear updated flag */ ++ if ( ioctl ( skfd, SIOCGIWSTATS, &wrq ) < 0 ) ++ wi->has_stats = 1; ++ ++ if ( !wi->has_stats ) { // no ioctl support, go to file ++ fp = fopen ( PROC_NET_WIRELESS, "r" ); ++ if ( fp ) { ++ while ( fgets ( bfr, sizeof ( bfr ), fp )) { ++ bfr [ sizeof ( bfr ) - 1 ] = '\0'; // no buffer overruns here! ++ strtok (( char * ) &bfr, "\n" ); // '\n' => '\0' ++ if ( strstr ( bfr, ifname ) && strstr ( bfr, ":" )) { ++ wi->has_stats = 1; ++ s = bfr; ++ s = strchr ( s, ':' ); s++; /* Skip ethX: */ ++ s = strtok ( s, " " ); /* ' ' => '\0' */ ++ sscanf ( s, "%hX", &wi->stats.status ); // status ++ ++ s = strtok ( NULL, " " ); // link quality ++ if ( strchr ( s, '.' ) != NULL ) ++ wi->stats.qual.updated |= 1; ++ sscanf ( s, "%hhd", &wi->stats.qual.qual ); ++ ++ s = strtok ( NULL, " " ); // signal level ++ if ( strchr ( s,'.' ) != NULL ) ++ wi->stats.qual.updated |= 2; ++ sscanf ( s, "%hhd", &wi->stats.qual.level ); ++ ++ s = strtok ( NULL, " " ); // noise level ++ if ( strchr ( s, '.' ) != NULL ) ++ wi->stats.qual.updated += 4; ++ sscanf ( s, "%hhd", &wi->stats.qual.noise ); ++ ++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.discard.nwid ); ++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.discard.code ); ++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.discard.fragment ); ++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.discard.retries ); ++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.discard.misc ); ++ s = strtok ( NULL, " " ); sscanf ( s, "%d", &wi->stats.miss.beacon ); ++ } ++ } ++ fclose ( fp ); ++ } ++ } ++ ++// printf ( "%s bfr: %s\n", "loadTables()", bfr ); ++} ++ ++/**************************************************************************** ++* * ++* displayWiExt() - show what I got from Wireless Extensions * ++* * ++****************************************************************************/ ++static void displayWiExt ( struct wireless_info info ) ++{ ++#ifdef DISPLAYWIEXT ++ int i; ++ char title[] = "displayWiExt() -"; ++ ++ printf ( "========================================\n" ); ++ printf ( "===> Wireless Extension IOCTL calls <===\n" ); ++ printf ( "========================================\n" ); ++ ++ if ( strlen ( info.name )) ++ printf ( "%s name: %s\n", "SIOCGIWNAME", info.name ); ++ else ++ printf ( "%s\n", "no info.name support" ); ++ ++ if ( info.has_nickname = 1 ) ++ printf ( "%s nickname: %s\n", "SIOCGIWNICKN", info.nickname ); ++ else ++ printf ( "%s %s\n", "SIOCGIWNICKN", " ===> no info.nickname support" ); ++ ++ if ( info.has_essid ) ++ printf ( "%s essid_on: %d essid: %s\n", "SIOCGIWESSID", info.essid_on, info.essid ); ++ else ++ printf ( "%s %s\n", "SIOCGIWESSID", " ===> no info.essid support" ); ++ ++ if ( info.has_range ) { ++ printf ( "%s throughput: %d\n", "SIOCGIWRANGE", info.range.throughput ); ++ printf ( "%s min_nwid: %d\n", "SIOCGIWRANGE", info.range.min_nwid ); ++ printf ( "%s max_nwid: %d\n", "SIOCGIWRANGE", info.range.max_nwid ); ++ printf ( "%s sensitivity: %d\n", "SIOCGIWRANGE", info.range.sensitivity ); ++ printf ( "%s num_bitrates: %d\n", "SIOCGIWRANGE", info.range.num_bitrates ); ++ for ( i = 0; i < info.range.num_bitrates; i++ ) ++ printf ( "%s bitrate[%d]: %d\n", "SIOCGIWRANGE", i, info.range.bitrate[i] ); ++ printf ( "%s min_rts: %d\n", "SIOCGIWRANGE", info.range.min_rts ); ++ printf ( "%s max_rts: %d\n", "SIOCGIWRANGE", info.range.max_rts ); ++ printf ( "%s min_frag: %d\n", "SIOCGIWRANGE", info.range.min_frag ); ++ printf ( "%s max_frag: %d\n", "SIOCGIWRANGE", info.range.max_frag ); ++ printf ( "%s min_pmp: %d\n", "SIOCGIWRANGE", info.range.min_pmp ); ++ printf ( "%s max_pmp: %d\n", "SIOCGIWRANGE", info.range.max_pmp ); ++ printf ( "%s min_pmt: %d\n", "SIOCGIWRANGE", info.range.min_pmt ); ++ printf ( "%s max_pmt: %d\n", "SIOCGIWRANGE", info.range.max_pmt ); ++ printf ( "%s pmp_flags: %d\n", "SIOCGIWRANGE", info.range.pmp_flags ); ++ printf ( "%s pmt_flags: %d\n", "SIOCGIWRANGE", info.range.pmt_flags ); ++ printf ( "%s pm_capa: %d\n", "SIOCGIWRANGE", info.range.pm_capa ); ++ printf ( "%s num_encoding_sizes: %d\n", "SIOCGIWRANGE", info.range.num_encoding_sizes ); ++ for ( i = 0; i < info.range.num_encoding_sizes; i++ ) ++ printf ( "%s encoding_size[%d]: %d\n", "SIOCGIWRANGE", i, info.range.encoding_size[i] ); ++ printf ( "%s max_encoding_tokens: %d\n", "SIOCGIWRANGE", info.range.max_encoding_tokens ); ++// printf ( "%s encoding_login_index: %d\n", "SIOCGIWRANGE", info.range.encoding_login_index ); ++ printf ( "%s txpower_capa: %d\n", "SIOCGIWRANGE", info.range.txpower_capa ); ++ printf ( "%s num_txpower: %d dBm\n", "SIOCGIWRANGE", info.range.num_txpower ); ++ for ( i = 0; i < info.range.num_txpower; i++ ) ++ printf ( "%s txpower[%d]: %d\n", "SIOCGIWRANGE", i, info.range.txpower[i] ); ++ printf ( "%s we_version_compiled: %d\n", "SIOCGIWRANGE", info.range.we_version_compiled ); ++ printf ( "%s we_version_source: %d\n", "SIOCGIWRANGE", info.range.we_version_source ); ++ printf ( "%s retry_capa: %d\n", "SIOCGIWRANGE", info.range.retry_capa ); ++ printf ( "%s retry_flags: %d\n", "SIOCGIWRANGE", info.range.retry_flags ); ++ printf ( "%s r_time_flags: %d\n", "SIOCGIWRANGE", info.range.r_time_flags ); ++ printf ( "%s min_retry: %d\n", "SIOCGIWRANGE", info.range.min_retry ); ++ printf ( "%s max_retry: %d\n", "SIOCGIWRANGE", info.range.max_retry ); ++ printf ( "%s min_r_time: %d\n", "SIOCGIWRANGE", info.range.min_r_time ); ++ printf ( "%s max_r_time: %d\n", "SIOCGIWRANGE", info.range.max_r_time ); ++ printf ( "%s num_channels: %d\n", "SIOCGIWRANGE", info.range.num_channels ); ++ printf ( "%s num_frequency: %d\n", "SIOCGIWRANGE", info.range.num_frequency ); ++ for ( i = 0; i < info.range.num_frequency; i++ ) ++ printf ( "%s freq[%d].i: %d freq[%d].e: %d freq[%d].m: %d\n", "SIOCGIWRANGE", ++ i, info.range.freq[i].i, i, info.range.freq[i].e, i, info.range.freq[i].m ); ++ } ++ else ++ printf ( "%s %s\n", "SIOCGIWRANGE", " ===> no info.range support" ); ++ ++ if ( info.has_nwid ) ++ printf ( "%s nwid - disabled: %d value: %X\n", "SIOCGIWNWID", info.nwid.disabled, info.nwid.value ); ++ else ++ printf ( "%s %s\n", "SIOCGIWNWID", " ===> no info.nwid support" ); ++ ++ if ( info.has_freq ) { ++// printf ( "%s freq: %g\n", "SIOCGIWFREQ", info.freq / GIGA ); ++ printf ( "%s freq: %g\n", "SIOCGIWFREQ", info.freq ); ++ } ++ else ++ printf ( "%s %s\n", "SIOCGIWFREQ", " ===> no info.freq support" ); ++ ++ if ( info.has_sens ) ++ printf ( "%s sens: %" PRIdPTR "\n", "SIOCGIWSENS", *(intptr_t *)&info.sens ); ++ else ++ printf ( "%s %s\n", "SIOCGIWSENS", " ===> no info.sens support" ); ++ ++ if ( info.has_key ) { ++ printf ( "%s key_size: %d key_flags: %d wepCurrentKey: %ld\n", ++ "SIOCGIWENCODE", info.key_size, info.key_flags, wepCurrentKey ); ++ printf ( "%s MODE: %d DISABLED: %d INDEX: %d OPEN: %d RESTRICTED: %d NOKEY: %d TEMP: %d\n", ++ "SIOCGIWENCODE", info.key_flags & IW_ENCODE_MODE, ++ info.key_flags & IW_ENCODE_DISABLED ? 1:0, info.key_flags & IW_ENCODE_INDEX, ++ info.key_flags & IW_ENCODE_OPEN ? 1:0, info.key_flags & IW_ENCODE_RESTRICTED ? 1:0, ++ info.key_flags & IW_ENCODE_NOKEY ? 1:0, info.key_flags & IW_ENCODE_TEMP ? 1:0 ); ++ } ++ else ++ printf ( "%s %s\n", "SIOCGIWENCODE", " ===> no info.key support" ); ++ ++ for ( i = 0; i < MAX_WEP_KEYS; i++ ) { ++ if ( wep[i].haveKey ) ++ printf ( "%s wep[%d].len: %ld wep[%d].key: %s\n", ++ "SIOCGIWENCODE", i, wep[i].len, i, wep[i].key ); ++ } ++ ++ if ( info.has_ap_addr ) ++ printf ( "%s ap_addr.sa_data: %02X:%02X:%02X:%02X:%02X:%02X ap_addr.sa_family: %d\n", ++ "SIOCGIWAP", ( UCHAR ) info.ap_addr.sa_data[0], ( UCHAR ) info.ap_addr.sa_data[1], ++ ( UCHAR ) info.ap_addr.sa_data[2], ( UCHAR ) info.ap_addr.sa_data[3], ++ ( UCHAR ) info.ap_addr.sa_data[4], ( UCHAR ) info.ap_addr.sa_data[5], ++ info.ap_addr.sa_family ); ++ else ++ printf ( "%s %s\n", "SIOCGIWAP", " ===> no ap_addr information" ); ++ ++ if ( info.has_bitrate ) ++ printf ( "%s bitrate: %" PRIdPTR " value: %d fixed: %d disabled: %d flags: %d\n", ++ "SIOCGIWRATE", *(intptr_t *)&info.bitrate, info.bitrate.value, info.bitrate.fixed, ++ info.bitrate.disabled, info.bitrate.flags ); ++ else ++ printf ( "%s %s\n", "SIOCGIWRATE", " ===> no info.bitrate support" ); ++ ++ if ( info.has_rts ) ++ printf ( "%s rts: %" PRIdPTR "\n", "SIOCGIWRTS", *(intptr_t *)&info.rts ); ++ else ++ printf ( "%s %s\n", "SIOCGIWRTS", " ===> no info.rts support" ); ++ ++ if ( info.has_frag ) ++ printf ( "%s frag: %" PRIdPTR "\n", "SIOCGIWFRAG", *(intptr_t *)&info.frag ); ++ else ++ printf ( "%s %s\n", "SIOCGIWFRAG", " ===> no info.frag support" ); ++ ++ if ( info.has_mode ) ++ printf ( "%s mode: %d\n", "SIOCGIWMODE", info.mode ); ++ else ++ printf ( "%s %s\n", "SIOCGIWMODE", " ===> no info.mode support" ); ++ ++ if ( info.has_power ) { ++ printf ( "%s power: %" PRIdPTR "\n", "SIOCGIWPOWER", *(intptr_t *)&info.power ); ++ printf ( "%s disabled: %d MIN: %d MAX: %d TIMEOUT: %d RELATIVE: %d\n", ++ "SIOCGIWPOWER", ++ info.power.disabled ? 1:0, ++ info.power.flags & IW_POWER_MIN ? 1:0, ++ info.power.flags & IW_POWER_MAX ? 1:0, ++ info.power.flags & IW_POWER_TIMEOUT ? 1:0, ++ info.power.flags & IW_POWER_RELATIVE ? 1:0 ); ++ printf ( "%s UNICAST: %d MULTICAST: %d ALL: %d FORCE: %d REPEATER: %d\n", ++ "SIOCGIWPOWER", ++ info.power.flags & IW_POWER_UNICAST_R ? 1:0, ++ info.power.flags & IW_POWER_MULTICAST_R ? 1:0, ++ info.power.flags & IW_POWER_ALL_R ? 1:0, ++ info.power.flags & IW_POWER_FORCE_S ? 1:0, ++ info.power.flags & IW_POWER_REPEATER ? 1:0 ); ++ } ++ else ++ printf ( "%s %s\n", "SIOCGIWPOWER", " ===> no info.power support" ); ++ ++ if ( info.has_retry ) ++ printf ( "%s retry: %" PRIdPTR "\n", "SIOCGIWRETRY", *(intptr_t *)&info.retry ); ++ else ++ printf ( "%s %s\n", "SIOCGIWRETRY", " ===> no info.retry support" ); ++ ++ if ( info.has_stats ) { ++ printf ( "%s status: %d\n", "SIOCGIWSTATS", info.stats.status ); ++ printf ( "%s qual.level: %d\n", "SIOCGIWSTATS", info.stats.qual.level ); ++ printf ( "%s qual.noise: %d\n", "SIOCGIWSTATS", info.stats.qual.noise ); ++ printf ( "%s qual.qual: %d\n", "SIOCGIWSTATS", info.stats.qual.qual ); ++ printf ( "%s qual.updated: %d\n", "SIOCGIWSTATS", info.stats.qual.updated ); ++ printf ( "%s discard.code: %d\n", "SIOCGIWSTATS", info.stats.discard.code ); ++ printf ( "%s discard.fragment: %d\n", "SIOCGIWSTATS", info.stats.discard.fragment ); ++ printf ( "%s discard.misc: %d\n", "SIOCGIWSTATS", info.stats.discard.misc ); ++ printf ( "%s discard.nwid: %d\n", "SIOCGIWSTATS", info.stats.discard.nwid ); ++ printf ( "%s discard.retries: %d\n", "SIOCGIWSTATS", info.stats.discard.retries ); ++ printf ( "%s miss.beacon: %d\n", "SIOCGIWSTATS", info.stats.miss.beacon ); ++ } ++ else ++ printf ( "%s %s\n", "SIOCGIWSTATS", " ===> no info.stats support" ); ++ ++ if ( info.txpower.flags & IW_TXPOW_MWATT ) ++ printf ( "%s txpower1: %d dBm disabled: %d fixed: %d flags: %d\n", "SIOCGIWRANGE", ++ mWatt2dbm ( info.txpower.value ), info.txpower.disabled, info.txpower.fixed, info.txpower.flags); ++ else ++ printf ( "%s txpower2: %d dBm disabled: %d fixed: %d flags: %d\n", "SIOCGIWRANGE", info.txpower.value, info.txpower.disabled, info.txpower.fixed, info.txpower.flags ); ++ ++ if ( info.has_range ) ++ if ( info.sens.value < 0 ) ++ printf ( "%s sens: %d dBm\n", "SIOCGIWRANGE", info.sens.value ); ++ else ++ printf ( "%s sens: %d/%d\n", "SIOCGIWRANGE", info.sens.value, info.range.sensitivity ); ++ ++ if ( info.has_range && ( info.stats.qual.level != 0 )) ++ if ( info.stats.qual.level > info.range.max_qual.level ) ++ /* Statistics are in dBm (absolute power measurement) */ ++ printf ( "%s Quality: %d/%d Signal level: %d dBm Noise level: %d dBm\n", ++ "SIOCGIWRANGE", ++ info.stats.qual.qual, info.range.max_qual.qual, ++ info.stats.qual.level - 0x100, ++ info.stats.qual.noise - 0x100 ); ++ else ++ printf ( "%s Quality: %d/%d Signal level: %d/%d Noise level: %d/%d", ++ "SIOCGIWRANGE", ++ info.stats.qual.qual, info.range.max_qual.qual, ++ info.stats.qual.level, info.range.max_qual.level, ++ info.stats.qual.noise, info.range.max_qual.noise ); ++ ++#endif // #ifdef DISPLAYWIEXT ++} ++ ++/**************************************************************************** ++* * ++* Linked List Functions * ++* * ++****************************************************************************/ ++/**************************************************************************** ++* * ++* addList() - add an entry to a linked list * ++* * ++****************************************************************************/ ++static void ++addList ( char *l, char *data, int len ) ++{ ++ char uid[256]; ++ avList_t *list; ++ ++ // NOTE: this assumes the UID is at the beginning of the ++ // data structure and that UIDs are strings ++ ++ list = ( avList_t * ) l; // NOTE: don't know how to get ++ strcpy ( uid, data ); // rid of compiler warning on ++ // LISTHEAD typecast ++ // create a new node and the data that goes in it ++ newNode = malloc ( sizeof ( struct avNode )); ++ newNode->data = malloc ( len ); ++ memcpy ( newNode->data, data, len ); ++ ++ // this deals with an empty list ++ if ( LIST_EMPTY ( list )) { ++ LIST_INSERT_HEAD ( list, newNode, nodes ); ++ return; ++ } ++ ++ // this deals with UIDs that match ++ for ( np = LIST_FIRST ( list ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ if ( strncmp ( uid, np->data, strlen ( uid )) == 0 ) { // found matching UID ++ LIST_INSERT_AFTER ( np, newNode, nodes ); ++ if ( np->data ) ++ free ( np->data ); ++ LIST_REMOVE ( np, nodes ); ++ free ( np ); ++ return; ++ } ++ } ++ ++ // this deals with inserting a new UID in the list ++ for ( np = LIST_FIRST ( list ); np != NULL; np = LIST_NEXT ( np, nodes )) { ++ lastNode = np; ++ if ( strncmp ( np->data, uid, strlen ( uid )) > 0 ) { // old ID > new ID AND ++ LIST_INSERT_BEFORE ( np, newNode, nodes ); ++ return; ++ } ++ } ++ ++ // this deals with a UID that needs to go on the end of the list ++ LIST_INSERT_AFTER ( lastNode, newNode, nodes ); ++ ++ return; ++} ++ ++/**************************************************************************** ++* * ++* initLists() - initialize all the linked lists * ++* * ++****************************************************************************/ ++static void initLists() ++{ ++ LIST_INIT ( &scList ); LIST_INIT ( &aaList ); LIST_INIT ( &dfList ); ++ LIST_INIT ( &kmList ); LIST_INIT ( &prList ); ++ LIST_INIT ( &opList ); LIST_INIT ( &coList ); ++ LIST_INIT ( &gaList ); LIST_INIT ( &riList ); LIST_INIT ( &poList ); ++ LIST_INIT ( &paList ); LIST_INIT ( &ptList ); LIST_INIT ( &pfList ); ++ LIST_INIT ( &pdList ); LIST_INIT ( &piList ); LIST_INIT ( &rdList ); ++ LIST_INIT ( &alList ); LIST_INIT ( &rtList ); LIST_INIT ( &rrList ); ++} ++/**************************************************************************** ++* * ++* flushLists() - flush all linked lists * ++* * ++****************************************************************************/ ++static void flushLists() ++{ ++ flushList (( char * ) &scList ); flushList (( char * ) &aaList ); ++ flushList (( char * ) &dfList ); flushList (( char * ) &kmList ); ++ flushList (( char * ) &prList ); ++ flushList (( char * ) &opList ); flushList (( char * ) &coList ); ++ flushList (( char * ) &gaList ); flushList (( char * ) &riList ); ++ flushList (( char * ) &poList ); flushList (( char * ) &paList ); ++ flushList (( char * ) &ptList ); flushList (( char * ) &pfList ); ++ flushList (( char * ) &pdList ); flushList (( char * ) &piList ); ++ flushList (( char * ) &rdList ); flushList (( char * ) &alList ); ++ flushList (( char * ) &rtList ); flushList (( char * ) &rrList ); ++} ++ ++/**************************************************************************** ++* * ++* flushList() - flush a linked list * ++* * ++****************************************************************************/ ++static void flushList ( char *l ) ++{ ++ avList_t *list; ++ ++ list = ( avList_t * ) l; // NOTE: don't know how to get ++ while ( !LIST_EMPTY ( list )) { // rid of compiler warning on ++ np = LIST_FIRST ( list ); // LISTHEAD typecast ++ if ( np->data ) ++ free ( np->data ); ++ LIST_REMOVE ( np, nodes ); ++ free ( np ); ++ } ++} ++ ++/**************************************************************************** ++* * ++* Utility Functions * ++* * ++****************************************************************************/ ++/**************************************************************************** ++* * ++* The following two routines were taken directly from iwlib.c * ++* * ++****************************************************************************/ ++ /* ++ * Open a socket. ++ * Depending on the protocol present, open the right socket. The socket ++ * will allow us to talk to the driver. ++ */ ++static int openSocket ( void ) ++{ ++ static const int families[] = { ++ AF_INET, AF_IPX, AF_AX25, AF_APPLETALK ++ }; ++ unsigned int i; ++ int sock; ++ ++ /* ++ * Now pick any (exisiting) useful socket family for generic queries ++ * Note : don't open all the socket, only returns when one matches, ++ * all protocols might not be valid. ++ * Workaround by Jim Kaba ++ * Note : in 99% of the case, we will just open the inet_sock. ++ * The remaining 1% case are not fully correct... ++ */ ++ ++ /* Try all families we support */ ++ for(i = 0; i < sizeof(families)/sizeof(int); ++i) { ++ /* Try to open the socket, if success returns it */ ++ sock = socket(families[i], SOCK_DGRAM, 0); ++ if(sock >= 0) ++ return sock; ++ } ++ ++ return -1; ++} ++ ++/*------------------------------------------------------------------*/ ++/* ++ * Convert a value in milliWatt to a value in dBm. ++ */ ++static int mWatt2dbm ( int in ) ++{ ++#ifdef WE_NOLIBM ++ /* Version without libm : slower */ ++ double fin = (double) in; ++ int res = 0; ++ ++ /* Split integral and floating part to avoid accumulating rounding errors */ ++ while(fin > 10.0) ++ { ++ res += 10; ++ fin /= 10.0; ++ } ++ while(fin > 1.000001) /* Eliminate rounding errors, take ceil */ ++ { ++ res += 1; ++ fin /= LOG10_MAGIC; ++ } ++ return(res); ++#else /* WE_NOLIBM */ ++ /* Version with libm : faster */ ++ return((int) (ceil(10.0 * log10((double) in)))); ++#endif /* WE_NOLIBM */ ++} ++ ++/**************************************************************************** ++* * ++* htob - converts hex string to binary * ++* * ++****************************************************************************/ ++static char *htob ( char *s ) ++{ ++ char nibl, *byt; ++ static char bin[20]; ++ ++ byt = bin; ++ ++ while ((nibl = *s++) && nibl != ' ') { /* While not end of string. */ ++ nibl -= ( nibl > '9') ? ('A' - 10): '0'; ++ *byt = nibl << 4; /* place high nibble */ ++ if((nibl = *s++) && nibl != ' ') { ++ nibl -= ( nibl > '9') ? ('A' - 10): '0'; ++ *byt |= nibl; /* place low nibble */ ++ } ++ else break; ++ ++byt; ++ } ++ *++byt = '\0'; ++ return ( bin ); ++} ++ ++/**************************************************************************** ++* * ++* hasChanged() - see if area has been changed from NULLs * ++* * ++****************************************************************************/ ++static int hasChanged ( char *loc, int len ) ++{ ++ char *wrk; ++ int changed = TRUE; ++ ++ wrk = malloc ( len ); ++ memset ( wrk, 0, len ); ++ if ( memcmp ( loc, wrk, len ) == 0 ) ++ changed = FALSE; ++ free ( wrk ); ++ ++ return ( changed ); ++} ++ +--- /dev/null ++++ b/agent/mibgroup/ieee802dot11.h +@@ -0,0 +1,732 @@ ++/**************************************************************************** ++* * ++* File Name: ieee802dot11.h * ++* Used By: * ++* * ++* Operating System: * ++* Purpose: * ++* * ++* Comments: * ++* * ++* Author: Larry Simmons * ++* lsimmons@avantcom.com * ++* www.avantcom.com * ++* * ++* Creation Date: 09/02/03 * ++* * ++* Ver Date Inits Modification * ++* ----- -------- ----- ------------ * ++* 0.0.1 09/02/03 LRS created * ++* 0.0.2 09/24/03 LRS wouldn't build after fresh ./configure * ++****************************************************************************/ ++/* This file was generated by mib2c and is intended for use as a mib module ++ for the ucd-snmp snmpd agent. */ ++#ifndef _MIBGROUP_IEEE802DOT11_H ++#define _MIBGROUP_IEEE802DOT11_H ++/* we may use header_generic and header_simple_table from the util_funcs module */ ++ ++/**************************************************************************** ++* Includes * ++****************************************************************************/ ++#include ++ ++/**************************************************************************** ++* Linked List Defines * ++****************************************************************************/ ++// here are some Linked List MACROS I wanted to use, ++// but curiously were not in /usr/includes/sys/queue.h ++ ++#ifndef LIST_EMPTY ++ #define LIST_EMPTY(head) ((head)->lh_first == NULL) ++#endif ++ ++#ifndef LIST_NEXT ++ #define LIST_NEXT(elm, field) ((elm)->field.le_next) ++#endif ++ ++#ifndef LIST_INSERT_BEFORE ++ #define LIST_INSERT_BEFORE(listelm, elm, field) do { \ ++ (elm)->field.le_prev = (listelm)->field.le_prev; \ ++ LIST_NEXT((elm), field) = (listelm); \ ++ *(listelm)->field.le_prev = (elm); \ ++ (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ ++ } while (0) ++#endif ++ ++#ifndef LIST_FIRST ++ #define LIST_FIRST(head) ((head)->lh_first) ++#endif ++ ++/**************************************************************************** ++* 802.11 MIB Defines * ++****************************************************************************/ ++#define SYS_STRING_LEN 256 ++#define MACADDR_LEN ( 6 * 2 ) + 5 ++#define OPER_RATE_SET_LEN 126 ++#define MAN_OUI_LEN ( 3 * 2 ) + 2 ++#define WEP_STR_LEN 64 ++#define SNMP_STR_LEN 128 ++#define TEXT_LEN 80 ++#define IFINDEX_LEN 4 ++#define IFNAME_LEN 16 ++#define MAX_WEP_KEYS 4 ++ ++#define AUTHENICATION_ALGORITHMS_INDEX_LEN 4 ++#define WEP_DEFAULT_KEY_INDEX_LEN 4 ++#define WEP_KEY_MAPPING_INDEX_LEN 4 ++#define GROUP_ADDRESS_INDEX_LEN 4 ++#define REG_DOMAIN_SUPPORT_INDEX_LEN 4 ++#define ANTENNA_LIST_INDEX_LEN 4 ++#define SUPPORTED_DATA_RATES_TX_INDEX_LEN 4 ++#define SUPPORTED_DATA_RATES_RX_INDEX_LEN 4 ++ ++#define SC_UID_LEN IFINDEX_LEN ++#define AA_UID_LEN IFINDEX_LEN + AUTHENICATION_ALGORITHMS_INDEX_LEN ++#define DF_UID_LEN IFINDEX_LEN + WEP_DEFAULT_KEY_INDEX_LEN ++#define KM_UID_LEN IFINDEX_LEN + WEP_KEY_MAPPING_INDEX_LEN ++#define PR_UID_LEN IFINDEX_LEN ++#define OP_UID_LEN IFINDEX_LEN ++#define CO_UID_LEN IFINDEX_LEN ++#define GA_UID_LEN IFINDEX_LEN + GROUP_ADDRESS_INDEX_LEN ++#define RI_UID_LEN IFINDEX_LEN ++#define PO_UID_LEN IFINDEX_LEN ++#define PA_UID_LEN IFINDEX_LEN ++#define PT_UID_LEN IFINDEX_LEN ++#define PF_UID_LEN IFINDEX_LEN ++#define PD_UID_LEN IFINDEX_LEN ++#define PI_UID_LEN IFINDEX_LEN ++#define RD_UID_LEN IFINDEX_LEN + REG_DOMAIN_SUPPORT_INDEX_LEN ++#define AL_UID_LEN IFINDEX_LEN + ANTENNA_LIST_INDEX_LEN ++#define RT_UID_LEN IFINDEX_LEN + SUPPORTED_DATA_RATES_TX_INDEX_LEN ++#define RR_UID_LEN IFINDEX_LEN + SUPPORTED_DATA_RATES_RX_INDEX_LEN ++ ++/**************************************************************************** ++* Linked List Structure * ++****************************************************************************/ ++struct avNode { ++ LIST_ENTRY ( avNode ) nodes; ++ char *data; // pointer to data ++}; ++ ++typedef LIST_HEAD ( , avNode ) avList_t; ++ ++/**************************************************************************** ++* 802.11 MIB structures * ++****************************************************************************/ ++/**************************************************************************** ++* dot11Smt Group * ++****************************************************************************/ ++/**************************************************************************** ++* dot11StationConfigTable * ++****************************************************************************/ ++static struct scTbl_data { ++ ++ char UID [ SC_UID_LEN + 1 ]; // unique ID ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ ++ char stationID [ MACADDR_LEN + 1 ]; // Default actual MacAddr ++ long mediumOccupancyLimit; ++ long CFPPollable; ++ long CFPPeriod; ++ long maxDuration; ++ long authenticationResponseTimeOut; ++ long privacyOptionImplemented; ++ long powerManagementMode; ++ char desiredSSID [ SNMP_STR_LEN + 1 ]; ++ long desiredBSSType; ++ char operationalRateSet [ OPER_RATE_SET_LEN + 1]; ++ long beaconPeriod; ++ long DTIMPeriod; ++ long associationResponseTimeOut; ++ long disAssociationReason; ++ char disAssociationStation [ MACADDR_LEN + 1 ]; ++ long deAuthenticationReason; ++ char deAuthenticationStation [ MACADDR_LEN + 1 ]; ++ long authenticateFailStatus; ++ char authenticateFailStation [ MACADDR_LEN + 1 ]; ++ ++ long haveStationID; ++ long haveMediumOccupancyLimit; ++ long haveCFPPollable; ++ long haveCFPPeriod; ++ long haveMaxDuration; ++ long haveAuthenticationResponseTimeOut; ++ long havePrivacyOptionImplemented; ++ long havePowerManagementMode; ++ long haveDesiredSSID; ++ long haveDesiredBSSType; ++ long haveOperationalRateSet; ++ long haveBeaconPeriod; ++ long haveDTIMPeriod; ++ long haveAssociationResponseTimeOut; ++ long haveDisAssociationReason; ++ long haveDisAssociationStation; ++ long haveDeAuthenticationReason; ++ long haveDeAuthenticationStation; ++ long haveAuthenticateFailStatus; ++ long haveAuthenticateFailStation; ++ ++} nSc, *sc = &nSc; ++ ++static avList_t scList; ++ ++/**************************************************************************** ++* dot11AuthenticationAlgorithmsTable * ++****************************************************************************/ ++static struct aaTbl_data { ++ ++ char UID [ AA_UID_LEN + 1 ]; ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ long authenticationAlgorithmsIndex; ++ ++ long authenticationAlgorithm; ++ long authenticationAlgorithmsEnable; ++ ++ long haveAuthenticationAlgorithm; ++ long haveAuthenticationAlgorithmsEnable; ++ ++} nAa, *aa = &nAa; ++ ++static avList_t aaList; ++ ++/**************************************************************************** ++* dot11WEPDefaultKeysTable * ++****************************************************************************/ ++static struct dfTbl_data { ++ ++ char UID [ DF_UID_LEN + 1 ]; ++ char ifName [ IFNAME_LEN + 1 ]; ++ ++ long ifIndex; // ifindex of card ++ long WEPDefaultKeyIndex; ++ ++ char WEPDefaultKeyValue [ WEP_STR_LEN + 1 ]; ++ long haveWEPDefaultKeyValue; ++ ++} nDf, *df = &nDf; ++ ++static avList_t dfList; ++ ++/**************************************************************************** ++* dot11WEPKeyMappingsTable * ++****************************************************************************/ ++static struct kmTbl_data { ++ ++ char UID [ KM_UID_LEN + 1 ]; ++ char ifName [ IFNAME_LEN + 1 ]; ++ ++ long ifIndex; ++ long WEPKeyMappingIndex; ++ ++ char WEPKeyMappingAddress [ MACADDR_LEN + 1 ]; ++ long WEPKeyMappingWEPOn; ++ char WEPKeyMappingValue [ WEP_STR_LEN + 1 ]; ++ long WEPKeyMappingStatus; ++ ++ long haveWEPKeyMappingIndex; ++ long haveWEPKeyMappingAddress; ++ long haveWEPKeyMappingWEPOn; ++ long haveWEPKeyMappingValue; ++ long haveWEPKeyMappingStatus; ++ ++} nKm, *km = &nKm; ++ ++static avList_t kmList; ++ ++/**************************************************************************** ++* dot11PrivacyTable * ++****************************************************************************/ ++static struct prTbl_data { ++ ++ char UID [ PR_UID_LEN + 1 ]; ++ char ifName [ IFNAME_LEN + 1 ]; ++ ++ long ifIndex; ++ ++ long privacyInvoked; ++ long WEPDefaultKeyID; ++ long WEPKeyMappingLength; ++ long excludeUnencrypted; ++ unsigned long WEPICVErrorCount; ++ unsigned long WEPExcludedCount; ++ ++ long havePrivacyInvoked; ++ long haveWEPDefaultKeyID; ++ long haveWEPKeyMappingLength; ++ long haveExcludeUnencrypted; ++ long haveWEPICVErrorCount; ++ long haveWEPExcludedCount; ++ ++} nPr, *pr = &nPr; ++ ++static avList_t prList; ++ ++/**************************************************************************** ++* dot11Mac Group * ++****************************************************************************/ ++/**************************************************************************** ++* dot11OperationTable * ++****************************************************************************/ ++static struct opTbl_data { ++ ++ char UID [ OP_UID_LEN + 1 ]; // unique ID ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ ++ char MACAddress [ MACADDR_LEN + 1 ]; ++ long RTSThreshold; ++ long shortRetryLimit; ++ long longRetryLimit; ++ long fragmentationThreshold; ++ long maxTransmitMSDULifetime; ++ long maxReceiveLifetime; ++ char manufacturerID [ SNMP_STR_LEN + 1 ]; ++ char productID [ SNMP_STR_LEN + 1 ]; ++ ++ long haveMACAddress; ++ long haveRTSThreshold; ++ long haveShortRetryLimit; ++ long haveLongRetryLimit; ++ long haveFragmentationThreshold; ++ long haveMaxTransmitMSDULifetime; ++ long haveMaxReceiveLifetime; ++ long haveManufacturerID; ++ long haveProductID; ++ ++} nOp, *op = &nOp; ++ ++static avList_t opList; ++ ++/**************************************************************************** ++* dot11CountersTable * ++****************************************************************************/ ++static struct coTbl_data { ++ ++ char UID [ CO_UID_LEN + 1 ]; // unique ID ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ ++ unsigned long transmittedFragmentCount; ++ unsigned long multicastTransmittedFrameCount; ++ unsigned long failedCount; ++ unsigned long retryCount; ++ unsigned long multipleRetryCount; ++ unsigned long frameDuplicateCount; ++ unsigned long RTSSuccessCount; ++ unsigned long RTSFailureCount; ++ unsigned long ACKFailureCount; ++ unsigned long receivedFragmentCount; ++ unsigned long multicastReceivedFrameCount; ++ unsigned long FCSErrorCount; ++ unsigned long transmittedFrameCount; ++ unsigned long WEPUndecryptableCount; ++ ++ long haveTransmittedFragmentCount; ++ long haveMulticastTransmittedFrameCount; ++ long haveFailedCount; ++ long haveRetryCount; ++ long haveMultipleRetryCount; ++ long haveFrameDuplicateCount; ++ long haveRTSSuccessCount; ++ long haveRTSFailureCount; ++ long haveACKFailureCount; ++ long haveReceivedFragmentCount; ++ long haveMulticastReceivedFrameCount; ++ long haveFCSErrorCount; ++ long haveTransmittedFrameCount; ++ long haveWEPUndecryptableCount; ++ ++} nCo, *co = &nCo; ++ ++static avList_t coList; ++ ++/**************************************************************************** ++* dot11GroupAddressesTable * ++****************************************************************************/ ++static struct gaTbl_data { ++ ++ char UID [ GA_UID_LEN + 1 ]; ++ char ifName [ IFNAME_LEN + 1 ]; ++ ++ long ifIndex; // ifindex of card ++ long groupAddressesIndex; ++ ++ char address [ MACADDR_LEN + 1 ]; ++ long groupAddressesStatus; ++ ++ long haveAddress; ++ long haveGroupAddressesStatus; ++ ++} nGa, *ga = &nGa; ++ ++static avList_t gaList; ++ ++/**************************************************************************** ++* dot11Res Group * ++****************************************************************************/ ++static char resourceTypeIDName[] = "RTID"; ++static long haveResourceTypeIDName = 1; ++ ++/**************************************************************************** ++* dot11ResourceInfoTable * ++****************************************************************************/ ++static struct riTbl_data { ++ ++ char UID [ RI_UID_LEN + 1 ]; // unique ID ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ ++ char manufacturerOUI [ MAN_OUI_LEN + 1 ]; ++ char manufacturerName [ SYS_STRING_LEN + 1 ]; ++ char manufacturerProductName [ SYS_STRING_LEN + 1 ]; ++ char manufacturerProductVersion [ SYS_STRING_LEN + 1 ]; ++ ++ char haveManufacturerOUI; ++ char haveManufacturerName; ++ char haveManufacturerProductName; ++ char haveManufacturerProductVersion; ++ ++} nRi, *ri = &nRi; ++ ++static avList_t riList; ++ ++/**************************************************************************** ++* dot11Phy Group * ++****************************************************************************/ ++/**************************************************************************** ++* dot11PhyOperationTable * ++****************************************************************************/ ++static struct poTbl_data { ++ ++ char UID [ PO_UID_LEN + 1 ]; // unique ID ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ ++ long PHYType; ++ long currentRegDomain; ++ long tempType; ++ ++ long havePHYType; ++ long haveCurrentRegDomain; ++ long haveTempType; ++ ++} nPo, *po = &nPo; ++ ++static avList_t poList; ++ ++/**************************************************************************** ++* dot11PhyAntennaEntry * ++****************************************************************************/ ++static struct paTbl_data { ++ ++ char UID [ PA_UID_LEN + 1 ]; // unique ID ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ ++ long currentTxAntenna; ++ long diversitySupport; ++ long currentRxAntenna; ++ ++ long haveCurrentTxAntenna; ++ long haveDiversitySupport; ++ long haveCurrentRxAntenna; ++ ++} nPa, *pa = &nPa; ++ ++static avList_t paList; ++ ++/**************************************************************************** ++* dot11PhyTxPowerTable * ++****************************************************************************/ ++static struct ptTbl_data { ++ ++ char UID [ PT_UID_LEN + 1 ]; // unique ID ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ ++ long numberSupportedPowerLevels; ++ long TxPowerLevel1; ++ long TxPowerLevel2; ++ long TxPowerLevel3; ++ long TxPowerLevel4; ++ long TxPowerLevel5; ++ long TxPowerLevel6; ++ long TxPowerLevel7; ++ long TxPowerLevel8; ++ long currentTxPowerLevel; ++ ++ long haveNumberSupportedPowerLevels; ++ long haveTxPowerLevel1; ++ long haveTxPowerLevel2; ++ long haveTxPowerLevel3; ++ long haveTxPowerLevel4; ++ long haveTxPowerLevel5; ++ long haveTxPowerLevel6; ++ long haveTxPowerLevel7; ++ long haveTxPowerLevel8; ++ long haveCurrentTxPowerLevel ; ++ ++} nPt, *pt = &nPt; ++ ++static avList_t ptList; ++ ++/**************************************************************************** ++* dot11PhyFHSSTable * ++****************************************************************************/ ++static struct pfTbl_data { ++ ++ char UID [ PF_UID_LEN + 1 ]; // unique ID ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ ++ long hopTime; ++ long currentChannelNumber; ++ long maxDwellTime; ++ long currentDwellTime; ++ long currentSet; ++ long currentPattern; ++ long currentIndex; ++ ++ long haveHopTime; ++ long haveCurrentChannelNumber; ++ long haveMaxDwellTime; ++ long haveCurrentDwellTime; ++ long haveCurrentSet; ++ long haveCurrentPattern; ++ long haveCurrentIndex; ++ ++} nPf, *pf = &nPf; ++ ++static avList_t pfList; ++ ++/**************************************************************************** ++* dot11PhyDSSSTable * ++****************************************************************************/ ++static struct pdTbl_data { ++ ++ char UID [ PD_UID_LEN + 1 ]; // unique ID ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ ++ long currentChannel; ++ long CCAModeSupported; ++ long currentCCAMode; ++ long EDThreshold; ++ ++ long haveCurrentChannel; ++ long haveCCAModeSupported ; ++ long haveCurrentCCAMode; ++ long haveEDThreshold; ++ ++} nPd, *pd = &nPd; ++ ++static avList_t pdList; ++ ++/**************************************************************************** ++* dot11PhyIRTable * ++****************************************************************************/ ++static struct piTbl_data { ++ ++ char UID [ PI_UID_LEN + 1 ]; // unique ID ++ char ifName [ IFNAME_LEN + 1 ]; // ifName of card ++ ++ long ifIndex; // ifindex of card ++ ++ long CCAWatchdogTimerMax; ++ long CCAWatchdogCountMax; ++ long CCAWatchdogTimerMin; ++ long CCAWatchdogCountMin; ++ ++ long haveCCAWatchdogTimerMax; ++ long haveCCAWatchdogCountMax; ++ long haveCCAWatchdogTimerMin; ++ long haveCCAWatchdogCountMin; ++ ++} nPi, *pi = &nPi; ++ ++static avList_t piList; ++ ++/**************************************************************************** ++* dot11RegDomainsSupportedTable * ++****************************************************************************/ ++static struct rdTbl_data { ++ ++ char UID [ RD_UID_LEN + 1 ]; ++ char ifName [ IFNAME_LEN + 1 ]; ++ ++ long ifIndex; // ifindex of card ++ long regDomainsSupportIndex; ++ ++ long regDomainsSupportValue; ++ long haveRegDomainsSupportValue; ++ ++} nRd, *rd = &nRd; ++ ++static avList_t rdList; ++ ++/**************************************************************************** ++* dot11AntennasListTable * ++****************************************************************************/ ++static struct alTbl_data { ++ ++ char UID [ AL_UID_LEN + 1 ]; ++ char ifName [ IFNAME_LEN + 1 ]; ++ ++ long ifIndex; // ifindex of card ++ long antennaListIndex; ++ ++ long supportedTxAntenna; ++ long supportedRxAntenna; ++ long diversitySelectionRx ; ++ ++ long haveSupportedTxAntenna; ++ long haveSupportedRxAntenna; ++ long haveDiversitySelectionRx ; ++ ++} nAl, *al = &nAl; ++ ++static avList_t alList; ++ ++/**************************************************************************** ++* dot11SupportedDataRatesTxTable * ++****************************************************************************/ ++static struct rtTbl_data { ++ ++ char UID [ RT_UID_LEN + 1 ]; ++ char ifName [ IFNAME_LEN + 1 ]; ++ ++ long ifIndex; // ifindex of card ++ long supportedDataRatesTxIndex; ++ ++ long supportedDataRatesTxValue; ++ long haveSupportedDataRatesTxValue; ++ ++} nRt, *rt = &nRt; ++ ++static avList_t rtList; ++ ++/**************************************************************************** ++* dot11SupportedDataRatesRxTable * ++****************************************************************************/ ++static struct rrTbl_data { ++ ++ char UID [ RR_UID_LEN + 1 ]; ++ char ifName [ IFNAME_LEN + 1 ]; ++ ++ long ifIndex; // ifindex of card ++ long supportedDataRatesRxIndex; ++ ++ long supportedDataRatesRxValue; ++ long haveSupportedDataRatesRxValue; ++ ++} nRr, *rr = &nRr; ++ ++static avList_t rrList; ++ ++/**************************************************************************** ++* Wireless Extensions Structures * ++****************************************************************************/ ++static long wepCurrentKey; ++static long haveWepCurrentKey; ++static struct wepTbl_data { ++ ++ long len; ++ char key [ WEP_STR_LEN + 1 ]; ++ long haveKey; ++ ++} wep[4]; ++ ++/**************************************************************************** ++* * ++****************************************************************************/ ++config_require(util_funcs) ++ ++/* function prototypes */ ++ ++void init_ieee802dot11 ( void ); ++FindVarMethod var_ieee802dot11; ++FindVarMethod var_dot11StationConfigTable; ++FindVarMethod var_dot11AuthenticationAlgorithmsTable; ++FindVarMethod var_dot11WEPDefaultKeysTable; ++FindVarMethod var_dot11WEPKeyMappingsTable; ++FindVarMethod var_dot11PrivacyTable; ++FindVarMethod var_dot11OperationTable; ++FindVarMethod var_dot11CountersTable; ++FindVarMethod var_dot11GroupAddressesTable; ++FindVarMethod var_dot11ResourceInfoTable; ++FindVarMethod var_dot11PhyOperationTable; ++FindVarMethod var_dot11PhyAntennaTable; ++FindVarMethod var_dot11PhyTxPowerTable; ++FindVarMethod var_dot11PhyFHSSTable; ++FindVarMethod var_dot11PhyDSSSTable; ++FindVarMethod var_dot11PhyIRTable; ++FindVarMethod var_dot11RegDomainsSupportedTable; ++FindVarMethod var_dot11AntennasListTable; ++FindVarMethod var_dot11SupportedDataRatesTxTable; ++FindVarMethod var_dot11SupportedDataRatesRxTable; ++ ++WriteMethod write_dot11StationID; ++WriteMethod write_dot11MediumOccupancyLimit; ++WriteMethod write_dot11CFPPeriod; ++WriteMethod write_dot11CFPMaxDuration; ++WriteMethod write_dot11AuthenticationResponseTimeOut; ++WriteMethod write_dot11PowerManagementMode; ++WriteMethod write_dot11DesiredSSID; ++WriteMethod write_dot11DesiredBSSType; ++WriteMethod write_dot11OperationalRateSet; ++WriteMethod write_dot11BeaconPeriod; ++WriteMethod write_dot11DTIMPeriod; ++WriteMethod write_dot11AssociationResponseTimeOut; ++WriteMethod write_dot11AuthenticationAlgorithmsEnable; ++WriteMethod write_dot11WEPDefaultKeyValue; ++WriteMethod write_dot11WEPKeyMappingAddress; ++WriteMethod write_dot11WEPKeyMappingWEPOn; ++WriteMethod write_dot11WEPKeyMappingValue; ++WriteMethod write_dot11WEPKeyMappingStatus; ++WriteMethod write_dot11PrivacyInvoked; ++WriteMethod write_dot11WEPDefaultKeyID; ++WriteMethod write_dot11WEPKeyMappingLength; ++WriteMethod write_dot11ExcludeUnencrypted; ++WriteMethod write_dot11RTSThreshold; ++WriteMethod write_dot11ShortRetryLimit; ++WriteMethod write_dot11LongRetryLimit; ++WriteMethod write_dot11FragmentationThreshold; ++WriteMethod write_dot11MaxTransmitMSDULifetime; ++WriteMethod write_dot11MaxReceiveLifetime; ++WriteMethod write_dot11Address; ++WriteMethod write_dot11GroupAddressesStatus; ++WriteMethod write_dot11CurrentRegDomain; ++WriteMethod write_dot11CurrentTxAntenna; ++WriteMethod write_dot11CurrentRxAntenna; ++WriteMethod write_dot11CurrentTxPowerLevel; ++WriteMethod write_dot11CurrentChannelNumber; ++WriteMethod write_dot11CurrentDwellTime; ++WriteMethod write_dot11CurrentSet; ++WriteMethod write_dot11CurrentPattern; ++WriteMethod write_dot11CurrentIndex; ++WriteMethod write_dot11CurrentChannel; ++WriteMethod write_dot11CurrentCCAMode; ++WriteMethod write_dot11EDThreshold; ++WriteMethod write_dot11CCAWatchdogTimerMax; ++WriteMethod write_dot11CCAWatchdogCountMax; ++WriteMethod write_dot11CCAWatchdogTimerMin; ++WriteMethod write_dot11CCAWatchdogCountMin; ++WriteMethod write_dot11SupportedTxAntenna; ++WriteMethod write_dot11SupportedRxAntenna; ++WriteMethod write_dot11DiversitySelectionRx; ++ ++void shutdown_ieee802dot11 ( void ); ++ ++#endif /* _MIBGROUP_IEEE802DOT11_H */ +--- /dev/null ++++ b/agent/mibgroup/iwlib.h +@@ -0,0 +1,509 @@ ++/* ++ * Wireless Tools ++ * ++ * Jean II - HPLB 97->99 - HPL 99->02 ++ * ++ * Common header for the Wireless Extension library... ++ * ++ * This file is released under the GPL license. ++ * Copyright (c) 1997-2002 Jean Tourrilhes ++ */ ++ ++#ifndef IWLIB_H ++#define IWLIB_H ++ ++/*#include "CHANGELOG.h"*/ ++ ++/***************************** INCLUDES *****************************/ ++ ++/* Standard headers */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include /* gethostbyname, getnetbyname */ ++#include /* struct ether_addr */ ++#ifdef HAVE_NET_IF_H ++#include ++#endif ++#include /* struct timeval */ ++#include ++ ++/* This is our header selection. Try to hide the mess and the misery :-( ++ * Don't look, you would go blind ;-) */ ++ ++#ifndef LINUX_VERSION_CODE ++#include ++#endif ++ ++/* Kernel headers 2.4.X + Glibc 2.2 - Mandrake 8.0, Debian 2.3, RH 7.1 ++ * Kernel headers 2.2.X + Glibc 2.2 - Slackware 8.0 */ ++#if defined(__GLIBC__) \ ++ && __GLIBC__ == 2 \ ++ && __GLIBC_MINOR__ >= 2 \ ++ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) ++//#define GLIBC22_HEADERS ++#define GENERIC_HEADERS ++ ++/* Kernel headers 2.4.X + Glibc 2.1 - Debian 2.2 upgraded, RH 7.0 ++ * Kernel headers 2.2.X + Glibc 2.1 - Debian 2.2, RH 6.1 */ ++#elif defined(__GLIBC__) \ ++ && __GLIBC__ == 2 \ ++ && __GLIBC_MINOR__ == 1 \ ++ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) ++//#define GLIBC_HEADERS ++#define GENERIC_HEADERS ++ ++/* Kernel headers 2.2.X + Glibc 2.0 - Debian 2.1 */ ++#elif defined(__GLIBC__) \ ++ && __GLIBC__ == 2 \ ++ && __GLIBC_MINOR__ == 0 \ ++ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0) \ ++ && LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) ++#define GLIBC_HEADERS ++#define KLUDGE_HEADERS ++ ++/* Note : is it really worth supporting kernel 2.0.X, knowing that ++ * we require WE v9, which is only available in 2.2.X and higher ? ++ * I guess one could use 2.0.x with an upgraded wireless.h... */ ++ ++/* Kernel headers 2.0.X + Glibc 2.0 - Debian 2.0, RH 5 */ ++#elif defined(__GLIBC__) \ ++ && __GLIBC__ == 2 \ ++ && __GLIBC_MINOR__ == 0 \ ++ && LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) \ ++ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0) ++#define GLIBC_HEADERS ++ ++/* Kernel headers 2.0.X + libc5 - old systems */ ++#elif defined(_LINUX_C_LIB_VERSION_MAJOR) \ ++ && _LINUX_C_LIB_VERSION_MAJOR == 5 \ ++ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,0,0) \ ++ && LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0) ++#define LIBC5_HEADERS ++ ++/* Musl */ ++#elif !defined(__GLIBC__) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) ++#define GENERIC_HEADERS ++ ++/* Unsupported combination */ ++#else ++#error "Your kernel/libc combination is not supported" ++#endif ++ ++#ifdef GENERIC_HEADERS ++/* Proposed by Dr. Michael Rietz , 27.3.2 */ ++/* If this works for all, it might be more stable on the long term - Jean II */ ++#include /* For ARPHRD_ETHER */ ++#include /* For AF_INET & struct sockaddr */ ++#include /* For struct sockaddr_in */ ++#include ++#endif /* GENERIC_HEADERS */ ++ ++#ifdef GLIBC22_HEADERS ++/* Added by Ross G. Miller , 3/28/01 */ ++#include /* For ARPHRD_ETHER */ ++#include /* For AF_INET & struct sockaddr */ ++#include ++#endif /* GLIBC22_HEADERS */ ++ ++#ifdef KLUDGE_HEADERS ++#include ++#endif /* KLUDGE_HEADERS */ ++ ++#ifdef GLIBC_HEADERS ++#include /* For ARPHRD_ETHER */ ++#include /* For AF_INET & struct sockaddr */ ++#include /* For struct sockaddr_in */ ++#endif /* KLUDGE_HEADERS || GLIBC_HEADERS */ ++ ++#ifdef LIBC5_HEADERS ++#include /* For AF_INET & struct sockaddr & socket() */ ++#include /* For ARPHRD_ETHER */ ++#include /* For struct sockaddr_in */ ++#endif /* LIBC5_HEADERS */ ++ ++/* Those 3 headers were previously included in wireless.h */ ++#include /* for "caddr_t" et al */ ++#include /* for "struct sockaddr" et al */ ++#include /* for IFNAMSIZ and co... */ ++ ++#ifdef WEXT_HEADER ++/* Private copy of Wireless extensions */ ++#include WEXT_HEADER ++#else /* !WEXT_HEADER */ ++/* System wide Wireless extensions */ ++#include ++#endif /* !WEXT_HEADER */ ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++/****************************** DEBUG ******************************/ ++ ++ ++/************************ CONSTANTS & MACROS ************************/ ++ ++/* Paths */ ++#define PROC_NET_WIRELESS "/proc/net/wireless" ++#define PROC_NET_DEV "/proc/net/dev" ++ ++/* Some useful constants */ ++#define KILO 1e3 ++#define MEGA 1e6 ++#define GIGA 1e9 ++/* For doing log10/exp10 without libm */ ++#define LOG10_MAGIC 1.25892541179 ++ ++/* Backward compatibility for Wireless Extension 9 */ ++#ifndef IW_POWER_MODIFIER ++#define IW_POWER_MODIFIER 0x000F /* Modify a parameter */ ++#define IW_POWER_MIN 0x0001 /* Value is a minimum */ ++#define IW_POWER_MAX 0x0002 /* Value is a maximum */ ++#define IW_POWER_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ ++#endif /* IW_POWER_MODIFIER */ ++ ++#ifndef IW_ENCODE_NOKEY ++#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not here */ ++#define IW_ENCODE_MODE 0xF000 /* Modes defined below */ ++#endif /* IW_ENCODE_NOKEY */ ++#ifndef IW_ENCODE_TEMP ++#define IW_ENCODE_TEMP 0x0400 /* Temporary key */ ++#endif /* IW_ENCODE_TEMP */ ++ ++/* More backward compatibility */ ++#ifndef SIOCSIWCOMMIT ++#define SIOCSIWCOMMIT SIOCSIWNAME ++#endif /* SIOCSIWCOMMIT */ ++ ++/****************************** TYPES ******************************/ ++ ++/* Shortcuts */ ++typedef struct iw_statistics iwstats; ++typedef struct iw_range iwrange; ++typedef struct iw_param iwparam; ++typedef struct iw_freq iwfreq; ++typedef struct iw_quality iwqual; ++typedef struct iw_priv_args iwprivargs; ++typedef struct sockaddr sockaddr; ++ ++/* Structure for storing all wireless information for each device ++ * This is pretty exhaustive... */ ++typedef struct wireless_info ++{ ++ char name[IFNAMSIZ + 1]; /* Wireless/protocol name */ ++ int has_nwid; ++ iwparam nwid; /* Network ID */ ++ int has_freq; ++ double freq; /* Frequency/channel */ ++ int has_sens; ++ iwparam sens; /* sensitivity */ ++ int has_key; ++ unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */ ++ int key_size; /* Number of bytes */ ++ int key_flags; /* Various flags */ ++ int has_essid; ++ int essid_on; ++ char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */ ++ int has_nickname; ++ char nickname[IW_ESSID_MAX_SIZE + 1]; /* NickName */ ++ int has_ap_addr; ++ sockaddr ap_addr; /* Access point address */ ++ int has_bitrate; ++ iwparam bitrate; /* Bit rate in bps */ ++ int has_rts; ++ iwparam rts; /* RTS threshold in bytes */ ++ int has_frag; ++ iwparam frag; /* Fragmentation threshold in bytes */ ++ int has_mode; ++ int mode; /* Operation mode */ ++ int has_power; ++ iwparam power; /* Power management parameters */ ++ int has_txpower; ++ iwparam txpower; /* Transmit Power in dBm */ ++ int has_retry; ++ iwparam retry; /* Retry limit or lifetime */ ++ ++ /* Stats */ ++ iwstats stats; ++ int has_stats; ++ iwrange range; ++ int has_range; ++} wireless_info; ++ ++/* Structure for storing all wireless information for each device ++ * This is a cut down version of the one above, containing only ++ * the things *truly* needed to configure a card. ++ * Don't add other junk, I'll remove it... */ ++typedef struct wireless_config ++{ ++ char name[IFNAMSIZ + 1]; /* Wireless/protocol name */ ++ int has_nwid; ++ iwparam nwid; /* Network ID */ ++ int has_freq; ++ double freq; /* Frequency/channel */ ++ int has_key; ++ unsigned char key[IW_ENCODING_TOKEN_MAX]; /* Encoding key used */ ++ int key_size; /* Number of bytes */ ++ int key_flags; /* Various flags */ ++ int has_essid; ++ int essid_on; ++ char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID (extended network) */ ++ int has_mode; ++ int mode; /* Operation mode */ ++} wireless_config; ++ ++typedef struct stream_descr ++{ ++ char * end; /* End of the stream */ ++ char * current; /* Current event in stream of events */ ++ char * value; /* Current value in event */ ++} stream_descr; ++ ++/* Prototype for handling display of each single interface on the ++ * system - see iw_enum_devices() */ ++typedef int (*iw_enum_handler)(int skfd, ++ char * ifname, ++ char * args[], ++ int count); ++ ++/**************************** PROTOTYPES ****************************/ ++/* ++ * All the functions in iwcommon.c ++ */ ++ ++/* ---------------------- SOCKET SUBROUTINES -----------------------*/ ++int ++ iw_sockets_open(void); ++void ++ iw_enum_devices(int skfd, ++ iw_enum_handler fn, ++ char * args[], ++ int count); ++/* --------------------- WIRELESS SUBROUTINES ----------------------*/ ++int ++ iw_get_range_info(int skfd, ++ char * ifname, ++ iwrange * range); ++int ++ iw_print_version_info(char * toolname); ++int ++ iw_get_priv_info(int skfd, ++ char * ifname, ++ iwprivargs * priv, ++ int maxpriv); ++int ++ iw_get_basic_config(int skfd, ++ char * ifname, ++ wireless_config * info); ++int ++ iw_set_basic_config(int skfd, ++ char * ifname, ++ wireless_config * info); ++/* --------------------- PROTOCOL SUBROUTINES --------------------- */ ++int ++ iw_protocol_compare(char * protocol1, ++ char * protocol2); ++/* -------------------- FREQUENCY SUBROUTINES --------------------- */ ++void ++ iw_float2freq(double in, ++ iwfreq * out); ++double ++ iw_freq2float(iwfreq * in); ++void ++ iw_print_freq(char * buffer, ++ double freq); ++int ++ iw_freq_to_channel(double freq, ++ struct iw_range * range); ++void ++ iw_print_bitrate(char * buffer, ++ int bitrate); ++/* ---------------------- POWER SUBROUTINES ----------------------- */ ++int ++ iw_dbm2mwatt(int in); ++int ++ iw_mwatt2dbm(int in); ++/* -------------------- STATISTICS SUBROUTINES -------------------- */ ++int ++ iw_get_stats(int skfd, ++ char * ifname, ++ iwstats * stats); ++void ++ iw_print_stats(char * buffer, ++ iwqual * qual, ++ iwrange * range, ++ int has_range); ++/* --------------------- ENCODING SUBROUTINES --------------------- */ ++void ++ iw_print_key(char * buffer, ++ unsigned char * key, ++ int key_size, ++ int key_flags); ++int ++ iw_in_key(char * input, ++ unsigned char * key); ++int ++ iw_in_key_full(int skfd, ++ char * ifname, ++ char * input, ++ unsigned char * key, ++ __u16 * flags); ++/* ----------------- POWER MANAGEMENT SUBROUTINES ----------------- */ ++void ++ iw_print_pm_value(char * buffer, ++ int value, ++ int flags); ++void ++ iw_print_pm_mode(char * buffer, ++ int flags); ++/* --------------- RETRY LIMIT/LIFETIME SUBROUTINES --------------- */ ++#if WIRELESS_EXT > 10 ++void ++ iw_print_retry_value(char * buffer, ++ int value, ++ int flags); ++#endif ++/* ----------------------- TIME SUBROUTINES ----------------------- */ ++void ++ iw_print_timeval(char * buffer, ++ const struct timeval * time); ++/* --------------------- ADDRESS SUBROUTINES ---------------------- */ ++int ++ iw_check_mac_addr_type(int skfd, ++ char * ifname); ++int ++ iw_check_if_addr_type(int skfd, ++ char * ifname); ++#if 0 ++int ++ iw_check_addr_type(int skfd, ++ char * ifname); ++#endif ++void ++ iw_ether_ntop(const struct ether_addr* eth, char* buf); ++char* ++ iw_ether_ntoa(const struct ether_addr* eth); ++int ++ iw_ether_aton(const char* bufp, struct ether_addr* eth); ++int ++ iw_in_inet(char *bufp, struct sockaddr *sap); ++int ++ iw_in_addr(int skfd, ++ char * ifname, ++ char * bufp, ++ struct sockaddr * sap); ++/* ----------------------- MISC SUBROUTINES ------------------------ */ ++int ++ iw_get_priv_size(int args); ++ ++#if WIRELESS_EXT > 13 ++/* ---------------------- EVENT SUBROUTINES ---------------------- */ ++void ++ iw_init_event_stream(struct stream_descr * stream, ++ char * data, ++ int len); ++int ++ iw_extract_event_stream(struct stream_descr * stream, ++ struct iw_event * iwe); ++#endif /* WIRELESS_EXT > 13 */ ++ ++/**************************** VARIABLES ****************************/ ++ ++extern const char * const iw_operation_mode[]; ++#define IW_NUM_OPER_MODE 7 ++ ++/************************* INLINE FUNTIONS *************************/ ++/* ++ * Functions that are so simple that it's more efficient inlining them ++ */ ++ ++/* ++ * Note : I've defined wrapper for the ioctl request so that ++ * it will be easier to migrate to other kernel API if needed ++ */ ++ ++/*------------------------------------------------------------------*/ ++/* ++ * Wrapper to push some Wireless Parameter in the driver ++ */ ++static inline int ++iw_set_ext(int skfd, /* Socket to the kernel */ ++ char * ifname, /* Device name */ ++ int request, /* WE ID */ ++ struct iwreq * pwrq) /* Fixed part of the request */ ++{ ++ /* Set device name */ ++ strncpy(pwrq->ifr_name, ifname, IFNAMSIZ); ++ /* Do the request */ ++ return(ioctl(skfd, request, pwrq)); ++} ++ ++/*------------------------------------------------------------------*/ ++/* ++ * Wrapper to extract some Wireless Parameter out of the driver ++ */ ++static inline int ++iw_get_ext(int skfd, /* Socket to the kernel */ ++ char * ifname, /* Device name */ ++ int request, /* WE ID */ ++ struct iwreq * pwrq) /* Fixed part of the request */ ++{ ++ /* Set device name */ ++ strncpy(pwrq->ifr_name, ifname, IFNAMSIZ); ++ /* Do the request */ ++ return(ioctl(skfd, request, pwrq)); ++} ++ ++/*------------------------------------------------------------------*/ ++/* Backwards compatibility ++ * Actually, those form are much easier to use when dealing with ++ * struct sockaddr... */ ++static inline char* ++iw_pr_ether(char* bufp, const unsigned char* addr) ++{ ++ iw_ether_ntop((const struct ether_addr *) addr, bufp); ++ return bufp; ++} ++/* Backwards compatibility */ ++static inline int ++iw_in_ether(const char *bufp, struct sockaddr *sap) ++{ ++ sap->sa_family = ARPHRD_ETHER; ++ return iw_ether_aton(bufp, (struct ether_addr *) sap->sa_data) ? 0 : -1; ++} ++ ++/*------------------------------------------------------------------*/ ++/* ++ * Create an Ethernet broadcast address ++ */ ++static inline void ++iw_broad_ether(struct sockaddr *sap) ++{ ++ sap->sa_family = ARPHRD_ETHER; ++ memset((char *) sap->sa_data, 0xFF, ETH_ALEN); ++} ++ ++/*------------------------------------------------------------------*/ ++/* ++ * Create an Ethernet NULL address ++ */ ++static inline void ++iw_null_ether(struct sockaddr *sap) ++{ ++ sap->sa_family = ARPHRD_ETHER; ++ memset((char *) sap->sa_data, 0x00, ETH_ALEN); ++} ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* IWLIB_H */ diff --git a/net-snmp-ssl/patches/751-gcc-14-fix.patch b/net-snmp-ssl/patches/751-gcc-14-fix.patch new file mode 100644 index 00000000..a217bb70 --- /dev/null +++ b/net-snmp-ssl/patches/751-gcc-14-fix.patch @@ -0,0 +1,10 @@ +--- a/agent/mib_modules.c ++++ b/agent/mib_modules.c +@@ -42,6 +42,7 @@ + #include + #include + #include "mib_module_includes.h" ++#include "mibgroup/ieee802dot11.h" + + static int need_shutdown = 0; + diff --git a/net-snmp-ssl/patches/900-musl-compat.patch b/net-snmp-ssl/patches/900-musl-compat.patch new file mode 100644 index 00000000..c4234dd2 --- /dev/null +++ b/net-snmp-ssl/patches/900-musl-compat.patch @@ -0,0 +1,13 @@ +--- a/agent/mibgroup/iwlib.h ++++ b/agent/mibgroup/iwlib.h +@@ -92,6 +92,10 @@ + #elif !defined(__GLIBC__) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) + #define GENERIC_HEADERS + ++/* Musl */ ++#elif !defined(__GLIBC__) && LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0) ++#define GENERIC_HEADERS ++ + /* Unsupported combination */ + #else + #error "Your kernel/libc combination is not supported" diff --git a/net-snmp-ssl/patches/990-remove-semicolon-check-in-macros.patch b/net-snmp-ssl/patches/990-remove-semicolon-check-in-macros.patch new file mode 100644 index 00000000..0abe7439 --- /dev/null +++ b/net-snmp-ssl/patches/990-remove-semicolon-check-in-macros.patch @@ -0,0 +1,130 @@ +--- a/configure.d/config_modules_agent ++++ b/configure.d/config_modules_agent +@@ -27,8 +27,6 @@ done + # + AC_MSG_CHECKING([for and configuring mib modules to use]) + +-AH_TOP([#define NETSNMP_REQUIRE_SEMICOLON extern void netsnmp_unused_function(void)]) +- + # set up the CPP command + MODULECPP="$CPP $PARTIALTARGETFLAGS $CPPFLAGS -DNETSNMP_FEATURE_CHECKING -I${srcdir}/include -I${srcdir}/agent/mibgroup" + if test "x$enable_mfd_rewrites" = "xyes"; then +@@ -194,7 +192,7 @@ while test "x$new_module_list" != "x"; d + # - mib_module => libnetsnmpmibs (default) + # - agent_module => libnetsnmpagent + # +- AH_TOP([#define config_belongs_in(x) NETSNMP_REQUIRE_SEMICOLON]) ++ AH_TOP([#define config_belongs_in(x)]) + module_type=mib_module + if test -f $srcdir/$mibdir/$i.h; then + changequote(, ) +@@ -279,7 +277,7 @@ while test "x$new_module_list" != "x"; d + # + # check if $i has any conflicts + # +- AH_TOP([#define config_exclude(x) NETSNMP_REQUIRE_SEMICOLON]) ++ AH_TOP([#define config_exclude(x)]) + new_list_excl=`$MODULECPP module_tmp_header.h | \ + $SED -n 's/.*config_exclude(\(.*\)).*/\1/p'` + if test "x$new_list_excl" != "x"; then +@@ -308,7 +306,7 @@ while test "x$new_module_list" != "x"; d + # + # check if $i has any architecture specific requirements + # +- AH_TOP([#define config_arch_require(x,y) NETSNMP_REQUIRE_SEMICOLON]) ++ AH_TOP([#define config_arch_require(x,y)]) + changequote(, ) + new_list_arch=`$MODULECPP module_tmp_header.h | \ + $SED -n 's/.*config_arch_require( *\([^ ]*\) *, *\([^ ]*\) *).*/\1-xarchx-\2/p'` +@@ -330,7 +328,7 @@ while test "x$new_module_list" != "x"; d + # macro: config_version_require((base, version, version-modules, ...)) + # - lists alternative modules used from different versions. + # +- AH_TOP([#define config_version_require(x) NETSNMP_REQUIRE_SEMICOLON]) ++ AH_TOP([#define config_version_require(x)]) + [new_list_alt3=`$MODULECPP module_tmp_header.h | \ + $AWK ' + BEGIN { +@@ -372,7 +370,7 @@ while test "x$new_module_list" != "x"; d + # + # check if $i has any other required modules + # +- AH_TOP([#define config_require(x) NETSNMP_REQUIRE_SEMICOLON]) ++ AH_TOP([#define config_require(x)]) + new_list="$new_list `$MODULECPP module_tmp_header.h | \ + $SED -n 's/.*config_require(\(.*\)).*/\1/p'`" + AC_MSG_MODULE_DBG(" $i will test: $new_list") +@@ -409,7 +407,7 @@ while test "x$new_module_list" != "x"; d + # + # check if $i has any mibs to add + # +- AH_TOP([#define config_add_mib(x) NETSNMP_REQUIRE_SEMICOLON]) ++ AH_TOP([#define config_add_mib(x)]) + new_mibs=`$MODULECPP module_tmp_header.h | \ + $SED -n 's/.*config_add_mib(\(.*\)).*/\1/p'` + if test "x$new_mibs" != "x"; then +@@ -456,7 +454,7 @@ while test "x$new_module_list" != "x"; d + # check for config_parse_dot_conf + # (generally not used any longer; old auto-load a .conf token) + # +- AH_TOP([#define config_parse_dot_conf(w,x,y,z) NETSNMP_REQUIRE_SEMICOLON]) ++ AH_TOP([#define config_parse_dot_conf(w,x,y,z)]) + changequote(, ) + $MODULECPP module_tmp_header.h | \ + $SED -n 's@.*config_parse_dot_conf(\([^)]*\), *\([^),]*\), *\([^),]*\), *\([^),]*\)).*@register_config_handler("snmpd",\1, \2, \3, \4);@p' >> $mibdir/mib_module_dot_conf.h +@@ -468,7 +466,7 @@ while test "x$new_module_list" != "x"; d + # + # check if $i has any errors, or warnings + # +- AH_TOP([#define config_error(x) NETSNMP_REQUIRE_SEMICOLON]) ++ AH_TOP([#define config_error(x)]) + error=`$MODULECPP module_tmp_header.h | \ + $SED -n 's/.*config_error(\(.*\)).*/\1/p'` + if test "x$error" != "x"; then +@@ -481,7 +479,7 @@ while test "x$new_module_list" != "x"; d + # macro: config_warning(warning text) + # - used to signal a configuration "warning" to be printed to the user + # +- AH_TOP([#define config_warning(x) NETSNMP_REQUIRE_SEMICOLON]) ++ AH_TOP([#define config_warning(x)]) + warning=`$MODULECPP module_tmp_header.h | \ + $SED -n 's/.*config_warning(\(.*\)).*/\1/p'` + if test "x$warning" != "x"; then +--- a/include/net-snmp/net-snmp-config.h.in ++++ b/include/net-snmp/net-snmp-config.h.in +@@ -36,25 +36,25 @@ + + /* definitions added by configure on-the-fly */ + +-#define config_parse_dot_conf(w,x,y,z) NETSNMP_REQUIRE_SEMICOLON ++#define config_parse_dot_conf(w,x,y,z) + +-#define config_error(x) NETSNMP_REQUIRE_SEMICOLON ++#define config_error(x) + +-#define config_warning(x) NETSNMP_REQUIRE_SEMICOLON ++#define config_warning(x) + +-#define NETSNMP_REQUIRE_SEMICOLON extern void netsnmp_unused_function(void) ++#define extern void netsnmp_unused_function(void) + +-#define config_belongs_in(x) NETSNMP_REQUIRE_SEMICOLON ++#define config_belongs_in(x) + +-#define config_exclude(x) NETSNMP_REQUIRE_SEMICOLON ++#define config_exclude(x) + +-#define config_arch_require(x,y) NETSNMP_REQUIRE_SEMICOLON ++#define config_arch_require(x,y) + +-#define config_version_require(x) NETSNMP_REQUIRE_SEMICOLON ++#define config_version_require(x) + +-#define config_require(x) NETSNMP_REQUIRE_SEMICOLON ++#define config_require(x) + +-#define config_add_mib(x) NETSNMP_REQUIRE_SEMICOLON ++#define config_add_mib(x) + + /* Define to 1 if using 'alloca.c'. */ + #undef C_ALLOCA diff --git a/pingcontrol/Makefile b/pingcontrol/Makefile index d10b798c..20f8ba56 100755 --- a/pingcontrol/Makefile +++ b/pingcontrol/Makefile @@ -1,9 +1,9 @@ -: + include $(TOPDIR)/rules.mk PKG_NAME:=pingcontrol PKG_VERSION:=1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_BUILD_DIR:=$(BUILD_DIR)/pingcontrol include $(INCLUDE_DIR)/package.mk diff --git a/pingcontrol/files/pingcontrol b/pingcontrol/files/pingcontrol index 63acc71d..ece5fa19 100755 --- a/pingcontrol/files/pingcontrol +++ b/pingcontrol/files/pingcontrol @@ -10,7 +10,6 @@ SW_BEFORE_MODRES=$(uci -q get pingcontrol.$1.sw_before_modres) SW_BEFORE_SYSRES=$(uci -q get pingcontrol.$1.sw_before_sysres) PING_OK=$(uci -q get pingcontrol.$1.ping_ok) -SILENT=$(uci -q get pingcontrol.$1.ping_silent) PING_LOST=$(uci -q get pingcontrol.$1.ping_lost) PING_RESTORED=$(uci -q get pingcontrol.$1.ping_restored) BEFORE_IFACE_DOWN=$(uci -q get pingcontrol.$1.before_iface_down) @@ -35,15 +34,8 @@ done while true; do for IP in $TESTIP do - [ -n $IFNAME ] && { - /bin/ping -w5 -c1 -s8 -I $IFNAME $IP &> /dev/null - STATUS=$? - } || { - /bin/ping -w5 -c1 -s8 $IP &> /dev/null - STATUS=$? - } - - if [[ "${STATUS}" -eq "0" ]]; then + /bin/ping -w5 -c1 -s8 -I $IFNAME $IP &> /dev/null + if [[ "$?" -eq "0" ]]; then let host_up_count++ else logger -t pingcontrol "$INSTANCE: Ping to host $IP lost" @@ -58,9 +50,7 @@ while true; do done if [[ "$host_up_count" -gt "0" ]]; then - [ "${SILENT}" != "1" ] && { - logger -t pingcontrol "$INSTANCE: Ping OK, reset counters" - } + logger -t pingcontrol "$INSTANCE: Ping OK, reset counters" if [[ "$lost_flag" -eq "1" ]]; then if [[ -n "$PING_RESTORED" ]]; then logger -t pingcontrol "$INSTANCE: Execute $PING_RESTORED" @@ -68,10 +58,8 @@ while true; do fi else if [[ -n "$PING_OK" ]]; then - [ "${SILENT}" != "1" ] && { - logger -t pingcontrol "$INSTANCE: Execute $PING_OK" - } - eval $PING_OK + logger -t pingcontrol "$INSTANCE: Execute $PING_OK" + eval $PING_OK fi fi host_up_count=0 @@ -111,4 +99,4 @@ while true; do fi sleep $CHECK_PERIOD -done +done \ No newline at end of file diff --git a/pingcontrol/files/pingcontrol.config b/pingcontrol/files/pingcontrol.config index b70754ed..1ecead9c 100644 --- a/pingcontrol/files/pingcontrol.config +++ b/pingcontrol/files/pingcontrol.config @@ -3,6 +3,5 @@ config pingcontrol 'pingcontrol' option check_period '30' option iface 'internet' option testip '8.8.8.8' - option ping_silent '1' option sw_before_modres '3' option sw_before_sysres '0' diff --git a/pingcontrol/files/pingcontrol.init b/pingcontrol/files/pingcontrol.init index 1a066cb9..217a6106 100755 --- a/pingcontrol/files/pingcontrol.init +++ b/pingcontrol/files/pingcontrol.init @@ -42,8 +42,3 @@ service_triggers() { procd_add_reload_trigger 'pingcontrol' procd_add_validation validate_pingcontrol_section } - -reload_service() { - stop - start -} diff --git a/pollmydevice/Makefile b/pollmydevice/Makefile new file mode 100644 index 00000000..68a2209d --- /dev/null +++ b/pollmydevice/Makefile @@ -0,0 +1,51 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=pollmydevice +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/pollmydevice + +PKG_MAINTAINER:=TELEOFIS + +include $(INCLUDE_DIR)/package.mk + +define Package/pollmydevice + SECTION:=utils + CATEGORY:=Utilities + TITLE:=PollMyDevice project + DEPENDS:=+libpthread +libuci +endef + +TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include +TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib + +define Package/pollmydevice/description + This package contains utility for sim check manage. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Package/pollmydevice/install + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/pollmydevice $(1)/sbin/ + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/pollmydevice.config $(1)/etc/config/pollmydevice + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/pollmydevice.init $(1)/etc/init.d/pollmydevice + $(INSTALL_DIR) $(1)/etc/pollmydevice + $(INSTALL_BIN) ./files/console $(1)/etc/pollmydevice/console + $(INSTALL_BIN) ./files/exp_board $(1)/etc/pollmydevice/exp_board + $(INSTALL_BIN) ./files/exp_port $(1)/etc/pollmydevice/exp_port + $(INSTALL_DIR) $(1)/etc/sysctl.d + $(CP) ./files/printk.sysctl $(1)/etc/sysctl.d/12-printk.conf + $(INSTALL_DIR) $(1)/usr/libexec/rpcd/ + $(INSTALL_BIN) ./files/pollmydevice.rpcd $(1)/usr/libexec/rpcd/pollmydevice + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/pollmydevice.defaults $(1)/etc/uci-defaults/30_pollmydevice +endef + +$(eval $(call BuildPackage,pollmydevice)) diff --git a/pollmydevice/files/console b/pollmydevice/files/console new file mode 100755 index 00000000..ad143be8 --- /dev/null +++ b/pollmydevice/files/console @@ -0,0 +1,54 @@ +#!/bin/sh + +disable() +{ + CHECK=$(grep -r "#::askconsole" /etc/inittab) + if [ -z "$CHECK" ]; then + sed -i -e "s/::askconsole/#::askconsole/g" /etc/inittab + CHECK=$(grep -r "#kernel.printk" /etc/sysctl.d/12-printk.conf) + if [ -n "$CHECK" ]; then + sed -i -e "s/#kernel.printk/kernel.printk/g" /etc/sysctl.d/12-printk.conf + fi + reboot + else + CHECK=$(grep -r "#kernel.printk" /etc/sysctl.conf) + if [ -n "$CHECK" ]; then + sed -i -e "s/#kernel.printk/kernel.printk/g" /etc/sysctl.d/12-printk.conf + reboot + fi + fi +} + +enable() +{ + CHECK=$(grep -r "#::askconsole" /etc/inittab) + if [ -n "$CHECK" ]; then + sed -i -e "s/#::askconsole/::askconsole/g" /etc/inittab + CHECK=$(grep -r "#kernel.printk" /etc/sysctl.d/12-printk.conf) + if [ -z "$CHECK" ]; then + sed -i -e "s/kernel.printk/#kernel.printk/g" /etc/sysctl.d/12-printk.conf + fi + reboot + else + CHECK=$(grep -r "#kernel.printk" /etc/sysctl.d/12-printk.conf) + if [ -z "$CHECK" ]; then + sed -i -e "s/kernel.printk/#kernel.printk/g" /etc/sysctl.d/12-printk.conf + reboot + fi + fi +} + +status() +{ + CHECK1=$(grep -r "#::askconsole" /etc/inittab) + CHECK2=$(grep -r "#kernel.printk" /etc/sysctl.d/12-printk.conf) + if [ -z "$CHECK1" -a -n "$CHECK2" ]; then + echo "activated" + else + echo "deactivated" + fi +} + +$1 + +exit 0 \ No newline at end of file diff --git a/pollmydevice/files/exp_board b/pollmydevice/files/exp_board new file mode 100755 index 00000000..badb6e18 --- /dev/null +++ b/pollmydevice/files/exp_board @@ -0,0 +1,40 @@ +#!/bin/sh + +uci set pollmydevice.3='interface' +uci set pollmydevice.3.mode='disabled' +uci set pollmydevice.3.desc='RS-232(1)' +uci set pollmydevice.3.devicename='/dev/com10' +uci set pollmydevice.3.baudrate='9600' +uci set pollmydevice.3.bytesize='8' +uci set pollmydevice.3.open_in_firewall='1' +uci set pollmydevice.4='interface' +uci set pollmydevice.4.mode='disabled' +uci set pollmydevice.4.desc='RS-232(2)' +uci set pollmydevice.4.devicename='/dev/com11' +uci set pollmydevice.4.baudrate='9600' +uci set pollmydevice.4.bytesize='8' +uci set pollmydevice.4.open_in_firewall='1' +uci set pollmydevice.5='interface' +uci set pollmydevice.5.mode='disabled' +uci set pollmydevice.5.desc='A1B1' +uci set pollmydevice.5.devicename='/dev/com12' +uci set pollmydevice.5.baudrate='9600' +uci set pollmydevice.5.bytesize='8' +uci set pollmydevice.5.open_in_firewall='1' +uci set pollmydevice.6='interface' +uci set pollmydevice.6.mode='disabled' +uci set pollmydevice.6.desc='A2B2' +uci set pollmydevice.6.devicename='/dev/com13' +uci set pollmydevice.6.baudrate='9600' +uci set pollmydevice.6.bytesize='8' +uci set pollmydevice.6.open_in_firewall='1' +uci set pollmydevice.7='interface' +uci set pollmydevice.7.mode='disabled' +uci set pollmydevice.7.desc='A3B3' +uci set pollmydevice.7.devicename='/dev/com14' +uci set pollmydevice.7.baudrate='9600' +uci set pollmydevice.7.bytesize='8' +uci set pollmydevice.7.open_in_firewall='1' +uci commit pollmydevice + +exit 0 \ No newline at end of file diff --git a/pollmydevice/files/exp_port b/pollmydevice/files/exp_port new file mode 100755 index 00000000..69b3f41b --- /dev/null +++ b/pollmydevice/files/exp_port @@ -0,0 +1,12 @@ +#!/bin/sh + +uci set pollmydevice.2='interface' +uci set pollmydevice.2.mode='disabled' +uci set pollmydevice.2.desc='A2B2' +uci set pollmydevice.2.devicename='/dev/com2' +uci set pollmydevice.2.baudrate='9600' +uci set pollmydevice.2.bytesize='8' +uci set pollmydevice.2.open_in_firewall='1' +uci commit pollmydevice + +exit 0 \ No newline at end of file diff --git a/pollmydevice/files/pollmydevice.config b/pollmydevice/files/pollmydevice.config new file mode 100755 index 00000000..69715786 --- /dev/null +++ b/pollmydevice/files/pollmydevice.config @@ -0,0 +1,41 @@ +config interface '0' + option mode 'disabled' + option desc 'AB' + option devicename '/dev/com1' + option baudrate '9600' + option bytesize '8' + option parity 'none' + option flowcontrol 'none' + option stopbits '1' + option server_port '33000' + option holdconntime '60' + option client_port '6008' + option client_host '' + option client_auth '0' + option client_timeout '600' + option modbus_gateway '0' + option quiet '0' + option pack_timeout '0' + option pack_size '0' + option open_in_firewall '1' + +config interface '1' + option mode 'disabled' + option desc 'console' + option devicename '/dev/com0' + option baudrate '9600' + option bytesize '8' + option parity 'none' + option flowcontrol 'none' + option stopbits '1' + option server_port '33001' + option holdconntime '60' + option client_port '6008' + option client_host '' + option client_auth '0' + option client_timeout '600' + option modbus_gateway '0' + option quiet '0' + option pack_timeout '0' + option pack_size '0' + option open_in_firewall '1' diff --git a/pollmydevice/files/pollmydevice.defaults b/pollmydevice/files/pollmydevice.defaults new file mode 100755 index 00000000..5d4de765 --- /dev/null +++ b/pollmydevice/files/pollmydevice.defaults @@ -0,0 +1,25 @@ +#!/bin/sh + +. /usr/share/libubox/jshn.sh +json_load "$(ubus call system board)" +json_get_var MODEL model +case "$MODEL" in + "TELEOFIS LT70") + uci set pollmydevice.0.rs485_mode='1' + uci commit pollmydevice + ;; + "TELEOFIS LT70U") + uci set pollmydevice.0.rs485_mode='1' + uci set pollmydevice.1.mode='server' + uci set pollmydevice.1.baudrate='115200' + uci commit pollmydevice + sleep 30 && /etc/pollmydevice/console disable & + ;; + "TELEOFIS RTUx68 RE-DE") + uci set pollmydevice.0.rs485_mode='1' + uci set pollmydevice.2.rs485_mode='1' + uci commit pollmydevice + ;; +esac + +exit 0 diff --git a/pollmydevice/files/pollmydevice.init b/pollmydevice/files/pollmydevice.init new file mode 100644 index 00000000..d246bd96 --- /dev/null +++ b/pollmydevice/files/pollmydevice.init @@ -0,0 +1,130 @@ +#!/bin/sh /etc/rc.common + +START=99 +STOP=10 +USE_PROCD=1 + +DIR=/sbin +PROG=pollmydevice + +error() +{ + echo "${initscript}:" "$@" 1>&2 +} + +check_client_id() +{ + [ ! -d "/etc/pollmydevice" ] && mkdir -p "/etc/pollmydevice" + [ ! -d "/tmp/pollmydevice" ] && mkdir -p "/tmp/pollmydevice" + INTERFACE=$1 + if [[ -e "/etc/pollmydevice/client_id$INTERFACE" ]]; then + cp /etc/pollmydevice/client_id$INTERFACE /tmp/pollmydevice/client_id$INTERFACE + else + . /usr/share/libubox/jshn.sh + json_load "$(ubus call system board)" + json_get_var MODEL model + case "$MODEL" in + "TELEOFIS LT70" | "TELEOFIS LT70U") + SERIALNUM=$(getinfo serialnum) + if [[ "$SERIALNUM" != "n/a" ]]; then + SERIALNUM="0x$SERIALNUM" + CLIENT_ID=$((SERIALNUM*100000+INTERFACE)) + fi + rs485_count=$(fw_printenv -n rs485_count 2>/dev/null) + if [[ "$rs485_count" == "2" ]]; then + if [ -e /etc/pollmydevice/exp_port ]; then + /etc/pollmydevice/exp_port + rm /etc/pollmydevice/exp_port + uci set pollmydevice.2.rs485_mode='1' + uci commit pollmydevice + fi + fi + ;; + "TELEOFIS RTUx68") + SERIALNUM=$((0x$(getserialnum))) + CLIENT_ID=$((SERIALNUM*100000+INTERFACE)) + ;; + "TELEOFIS RTUx68 RE-DE") + SERIALNUM=$((0x$(getserialnum))) + CLIENT_ID=$((SERIALNUM*100000+INTERFACE)) + if [ -e /etc/pollmydevice/exp_port ]; then + /etc/pollmydevice/exp_port + rm /etc/pollmydevice/exp_port + fi + ;; + esac + [[ -n "$CLIENT_ID" ]] && echo $CLIENT_ID > /tmp/pollmydevice/client_id$INTERFACE + fi +} + +clear_firewall_settings() +{ + RULE=$(uci show firewall | grep -m1 port-pollmydevice) + while [[ -n "$RULE" ]]; do + RULE_N=$(echo $RULE | cut -d[ -f2 | cut -d] -f1) + uci delete firewall.@rule[$RULE_N] + RULE=$(uci show firewall | grep -m1 port-pollmydevice) + done + uci commit firewall +} + +open_firewall_port() +{ + config_get MODE "$1" mode + if [[ "$MODE" == "server" ]]; then + config_get OPEN "$1" open_in_firewall + if [[ "$OPEN" -eq "1" ]]; then + config_get DESCRIPTION "$1" desc + config_get PORT "$1" server_port + if [[ -n "$PORT" ]] && [[ -n "$DESCRIPTION" ]]; then + DESCRIPTION=$(echo $DESCRIPTION | tr -d ' ') + RULE=$(uci add firewall rule) + uci set firewall.$RULE.name=$DESCRIPTION-$1-port-pollmydevice + uci set firewall.$RULE.src='wan' + uci set firewall.$RULE.proto='tcp' + uci set firewall.$RULE.target='ACCEPT' + uci set firewall.$RULE.dest_port=$PORT + uci commit firewall + fi + fi + fi +} + +start_service_daemon() +{ + procd_open_instance + procd_set_param command "$DIR/$PROG" + procd_set_param respawn ${respawn_threshold:-360} ${respawn_timeout:-5} ${respawn_retry:-0} + procd_close_instance +} + +start_service() +{ + config_load 'pollmydevice' + config_foreach check_client_id 'interface' + clear_firewall_settings + config_foreach open_firewall_port 'interface' + /etc/init.d/firewall restart 2>/dev/null + start_service_daemon +} + +service_triggers() +{ + procd_add_reload_trigger 'pollmydevice' +} + +stop() +{ + service_stop $DIR/$PROG +} + +# reload_service() +# { +# service_stop $DIR/$PROG +# start_service +# } + +reload_service() { + stop + start +} diff --git a/pollmydevice/files/pollmydevice.rpcd b/pollmydevice/files/pollmydevice.rpcd new file mode 100755 index 00000000..541ac141 --- /dev/null +++ b/pollmydevice/files/pollmydevice.rpcd @@ -0,0 +1,34 @@ +#!/bin/sh + +case "$1" in + list) + echo '{ "con_on": { }, "con_off": { }, "status": { }, "get_id": { } }' + ;; + call) + case "$2" in + con_on) + /etc/pollmydevice/console enable + echo '{ "con_on": "done" }' + ;; + con_off) + /etc/pollmydevice/console disable + echo '{ "con_off": "done" }' + ;; + status) + status=$(/etc/pollmydevice/console status) + echo "{ \"status\": \"$status\" }" + ;; + get_id) + echo '{' + for num in 0 1 2 3 4 5 6 7 + do + value=$(cat /tmp/pollmydevice/client_id$num) + echo "\"id$num\": \"$value\"," + done + value=$(cat /tmp/pollmydevice/client_id8) + echo "\"id8\": \"$value\"" + echo '}' + ;; + esac + ;; +esac \ No newline at end of file diff --git a/pollmydevice/files/printk.sysctl b/pollmydevice/files/printk.sysctl new file mode 100755 index 00000000..3cbd44e0 --- /dev/null +++ b/pollmydevice/files/printk.sysctl @@ -0,0 +1 @@ +#kernel.printk=0 4 1 7 \ No newline at end of file diff --git a/pollmydevice/src/.vscode/settings.json b/pollmydevice/src/.vscode/settings.json new file mode 100644 index 00000000..7ae8d5be --- /dev/null +++ b/pollmydevice/src/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "cerrno": "cpp", + "thread": "cpp" + } +} \ No newline at end of file diff --git a/pollmydevice/src/Makefile b/pollmydevice/src/Makefile new file mode 100644 index 00000000..6c57a43e --- /dev/null +++ b/pollmydevice/src/Makefile @@ -0,0 +1,14 @@ +CC = gcc +CFLAGS = -Os -Wall -Wmissing-declarations -g3 +LDLIBS = -luci -lpthread -lubox + +PROGRAMS=pollmydevice + +all: $(PROGRAMS) + +pollmydevice: pollmydevice.o crc16.o modbus.o client_list.o + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +clean: + rm -f *.o $(PROGRAMS) + diff --git a/pollmydevice/src/client_list.c b/pollmydevice/src/client_list.c new file mode 100644 index 00000000..821dad12 --- /dev/null +++ b/pollmydevice/src/client_list.c @@ -0,0 +1,101 @@ +#include +#include + +#include "client_list.h" + +struct client_list { + int descr; + struct client_list *next; +}; + +struct client_list *head = NULL; +struct client_list *request = NULL; + +struct client_list * get_end_list() +{ + struct client_list * current = head; + if (current == NULL) + { + return NULL; + } + while (current->next != NULL) + { + current=current->next; + } + return current; + +} + +void client_insert(int new_descr) +{ + struct client_list *end=NULL; + if (head == NULL) + { + head = malloc(sizeof(struct client_list)); + if (head == NULL){ + return; + } + head->descr = new_descr; + head->next = NULL; + return; + } + end = get_end_list(); + if (end==NULL){ + return; + } + struct client_list *new_client =(struct client_list *) malloc(sizeof(struct client_list)); + if(new_client==NULL) + { + return; + } + new_client->descr = new_descr; + new_client->next = NULL; + end->next = new_client; +} + +void start_request_descr() +{ + request=head; +} + +int get_next_descr(int *descr) +{ + if(request==NULL) + { + return 1; + } + *descr=request->descr; + request=request->next; + return 0; +} + +void remove_descr(int descr) +{ + struct client_list *current = head; + struct client_list *prev = NULL; + if(current==NULL) + { + return; + } + + + while(current->descr!=descr) + { + prev=current; + current=current->next; + if(current==NULL) + { + return; + } + } + + if(current!=head){ + prev->next=current->next; + } else { + head=head->next; + } + free(current); + start_request_descr(); + +} + diff --git a/pollmydevice/src/client_list.h b/pollmydevice/src/client_list.h new file mode 100644 index 00000000..71e501dd --- /dev/null +++ b/pollmydevice/src/client_list.h @@ -0,0 +1,9 @@ +#ifndef _CLIENT_LIST_H +#define _CLIENT_LIST_H + +void start_request_descr(); +void client_insert(int new_descr); +int get_next_descr(int *descr); +void remove_descr(int descr); + +#endif \ No newline at end of file diff --git a/pollmydevice/src/crc16.c b/pollmydevice/src/crc16.c new file mode 100644 index 00000000..e5efb2a3 --- /dev/null +++ b/pollmydevice/src/crc16.c @@ -0,0 +1,79 @@ +/* + * OpenMODBUS/TCP to RS-232/485 MODBUS RTU gateway + * + * crc16.c - Cyclic Redundant Checks calculating + * + * Copyright (c) 2002-2003, 2013, Victor Antonovich (v.antonovich@gmail.com) + * + * Redistribution and use 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. + * + * 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 REGENTS 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. + * + * $Id: crc16.c,v 1.3 2015/02/25 10:33:57 kapyar Exp $ + */ + +#include "crc16.h" + +unsigned short +crc_16_tab[] = { + 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, + 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, + 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, + 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, + 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, + 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, + 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, + 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, + 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, + 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, + 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, + 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, + 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, + 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, + 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, + 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, + 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, + 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, + 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, + 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, + 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, + 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, + 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, + 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, + 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, + 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, + 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, + 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, + 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, + 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, + 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, + 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 +}; + +unsigned short +crc16(unsigned char *buf, unsigned int bsize) +{ + unsigned short crc = 0xffff; + while (bsize--) + crc = (unsigned short)(crc >> 8) ^ crc_16_tab[(crc ^ *buf++) & 0xff]; + return crc; +} diff --git a/pollmydevice/src/crc16.h b/pollmydevice/src/crc16.h new file mode 100644 index 00000000..041bc607 --- /dev/null +++ b/pollmydevice/src/crc16.h @@ -0,0 +1,41 @@ +/* + * OpenMODBUS/TCP to RS-232/485 MODBUS RTU gateway + * + * crc16.h - Cyclic Redundant Checks calculating + * + * Copyright (c) 2002-2003, 2013, Victor Antonovich (v.antonovich@gmail.com) + * + * Redistribution and use 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. + * + * 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 REGENTS 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. + * + * $Id: crc16.h,v 1.3 2015/02/25 10:33:57 kapyar Exp $ + */ + +#ifndef _CRC_H +#define _CRC_H + +//#include "globals.h" + +unsigned short crc16(unsigned char *buf, unsigned int bsize); + +#endif /*_CRC_H */ diff --git a/pollmydevice/src/globals.h b/pollmydevice/src/globals.h new file mode 100644 index 00000000..0bd19be5 --- /dev/null +++ b/pollmydevice/src/globals.h @@ -0,0 +1,103 @@ +/* + * OpenMODBUS/TCP to RS-232/485 MODBUS RTU gateway + * + * globals.h - global definitions + * + * Copyright (c) 2002-2003, 2013, Victor Antonovich (v.antonovich@gmail.com) + * + * Redistribution and use 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. + * + * 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 REGENTS 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. + * + * $Id: globals.h,v 1.4 2015/02/25 10:33:58 kapyar Exp $ + */ + +#ifndef _GLOBALS_H +#define _GLOBALS_H + +/* Include global configuration header file */ +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_LIBUTIL +# include +#endif + +/* + * Uncomment this for enabling logging facility + */ +#define LOG +#ifdef LOG +/* uncomment this line for extra debug log info */ +# define DEBUG +#endif + +/* + * Useful min/max macroses + */ +#define MAX(a, b) ( (a > b) ? a : b ) +#define MIN(a, b) ( (a < b) ? a : b ) + +/* + * Boolean constants + */ +#define FALSE 0 +#define TRUE !FALSE + +/* + * Constants + */ +#define RC_OK 0 +#define RC_ERR -1 +#define RC_BREAK -2 +#define RC_TIMEOUT -3 +#define RC_AOPEN -4 +#define RC_ACLOSE -5 + +/* Internal string buffers size */ +#if defined(PATH_MAX) +# define INTBUFSIZE PATH_MAX +#else +# define INTBUFSIZE 1023 +#endif + +#endif diff --git a/pollmydevice/src/log.h b/pollmydevice/src/log.h new file mode 100644 index 00000000..88687da4 --- /dev/null +++ b/pollmydevice/src/log.h @@ -0,0 +1,18 @@ +#ifndef _log_h +#define _log_h + +#include +#include + +#define LOG(fmt, ...) do { \ + syslog(LOG_NOTICE,"pollmydevice: "fmt, ## __VA_ARGS__); \ + fprintf(stderr, "pollmydevice: "fmt, ## __VA_ARGS__); \ + } while (0) + +#define ERROR(fmt, ...) do { \ + syslog(LOG_ERR,"pollmydevice: "fmt, ## __VA_ARGS__); \ + fprintf(stderr, "pollmydevice: "fmt, ## __VA_ARGS__); \ + } while (0) + +#endif + diff --git a/pollmydevice/src/modbus.c b/pollmydevice/src/modbus.c new file mode 100644 index 00000000..543fb3dc --- /dev/null +++ b/pollmydevice/src/modbus.c @@ -0,0 +1,93 @@ +/* + * OpenMODBUS/TCP to RS-232/485 MODBUS RTU gateway + * + * modbus.c - MODBUS protocol related procedures + * + * Copyright (c) 2002-2003, 2013, Victor Antonovich (v.antonovich@gmail.com) + * + * Redistribution and use 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. + * + * 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 REGENTS 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. + * + * $Id: modbus.c,v 1.3 2015/02/25 10:33:58 kapyar Exp $ + */ + +#include "modbus.h" + +#define RC_OK 0 +#define RC_ERR -1 +#define RC_BREAK -2 +#define RC_TIMEOUT -3 +#define RC_AOPEN -4 +#define RC_ACLOSE -5 +/* + * Check CRC of MODBUS frame + * Parameters: FRAME - address of the frame, + * LEN - frame length; + * Return: 0 if CRC failed, + * non-zero otherwise + */ +int +modbus_crc_correct(unsigned char *frame, unsigned int len) +{ + return (!crc16(frame, len)); +} + +/* + * Write CRC to MODBUS frame + * Parameters: FRAME - address of the frame, + * LEN - frame length; + * Return: none + */ +void +modbus_crc_write(unsigned char *frame, unsigned int len) +{ + WORD_WR_LE(frame + len, crc16(frame, len)); +} + +/* + * Write exception response to OpenMODBUS request + * Parameters: PACKET - address of the request packet, + * CODE - exception code; + * Return: none + */ +void +modbus_ex_write(unsigned char *packet, unsigned char code) +{ + MB_HDR(packet, MB_FCODE) |= 0x80; + MB_HDR(packet, MB_DATA) = code; + WORD_WR_BE(packet + MB_LENGTH_H, MB_EX_LEN); +} + +/* + * Check MODBUS packet header consistency + * Parameters: HEADER - address of the header + * Return: RC_OK if (mostly) all is right, RC_ERR otherwise + */ +int +modbus_check_header(unsigned char *packet) +{ + return (MB_HDR(packet, MB_PROTO_ID_H) == 0 && + MB_HDR(packet, MB_PROTO_ID_L) == 0 && + MB_HDR(packet, MB_LENGTH_H) == 0 && + MB_HDR(packet, MB_LENGTH_L) > 0) ? RC_OK : RC_ERR; +} diff --git a/pollmydevice/src/modbus.h b/pollmydevice/src/modbus.h new file mode 100644 index 00000000..13a19df3 --- /dev/null +++ b/pollmydevice/src/modbus.h @@ -0,0 +1,96 @@ +/* + * OpenMODBUS/TCP to RS-232/485 MODBUS RTU gateway + * + * modbus.h - MODBUS protocol related procedures + * + * Copyright (c) 2002-2003, 2013, Victor Antonovich (v.antonovich@gmail.com) + * + * Redistribution and use 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. + * + * 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 REGENTS 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. + * + * $Id: modbus.h,v 1.3 2015/02/25 10:33:57 kapyar Exp $ + */ + +#ifndef _MODBUS_H +#define _MODBUS_H + +//#include "globals.h" +#include "crc16.h" + +/* + * Macros for invoking data from MODBUS packet header + */ +#define MB_HDR(p, d) ( *(p + d) ) + +/* + * MODBUS frame lengths + */ +#define MB_EX_LEN 3 +#define MB_MIN_LEN 4 +#define MB_MAX_LEN 256 + +/* + * Macroses for word operations + */ +#define HIGH(w) ( (unsigned char)(((w) >> 8) & 0xff) ) +#define LOW(w) ( (unsigned char)((w) & 0xff) ) +#define WORD_WR_BE(p, w) do \ + { *(p) = (unsigned char)(((w) >> 8) & 0xff); \ + *(p + 1) = (unsigned char)((w) & 0xff); } \ + while (0); +#define WORD_RD_BE(p) ( (((unsigned short)*(p) << 8) & 0xff00) + \ + (*(p + 1) & 0xff) ) +#define WORD_WR_LE(p, w) do \ + { *(p) = (unsigned char)((w) & 0xff); \ + *(p + 1) = (unsigned char)(((w) >> 8) & 0xff); } \ + while (0); +#define WORD_RD_LE(p) ( (((unsigned short)*(p + 1) << 8) & 0xff00) + \ + (*(p) & 0xff) ) + +/* + * MODBUS packet structure + */ +#define MB_TRANS_ID_H 0 /* transaction ID high byte */ +#define MB_TRANS_ID_L 1 /* transaction ID low byte */ +#define MB_PROTO_ID_H 2 /* protocol ID high byte */ +#define MB_PROTO_ID_L 3 /* protocol ID low byte */ +#define MB_LENGTH_H 4 /* length field high byte */ +#define MB_LENGTH_L 5 /* length field low byte */ +#define MB_UNIT_ID 6 /* unit identifier */ +#define MB_FCODE 7 /* function code */ +#define MB_DATA 8 /* MODBUS data */ + +/* + * Exception codes + */ +#define MB_EX_CRC 4 +#define MB_EX_TIMEOUT 0x0B + +/* Prototypes */ +int modbus_crc_correct(unsigned char *frame, unsigned int len); +void modbus_crc_write(unsigned char *frame, unsigned int len); +void modbus_ex_write(unsigned char *packet, unsigned char code); +int modbus_check_header(unsigned char *packet); + + +#endif /* _MODBUS_H */ diff --git a/pollmydevice/src/pollmydevice.c b/pollmydevice/src/pollmydevice.c new file mode 100755 index 00000000..89107706 --- /dev/null +++ b/pollmydevice/src/pollmydevice.c @@ -0,0 +1,2083 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "uci.h" +#include "log.h" + +//MODBUS +#include "modbus.h" +#include "crc16.h" + +#include "client_list.h" + + +#define MODE_DISABLED 0 +#define MODE_SERVER 1 +#define MODE_CLIENT 2 + +#define PARITY_NONE 0 +#define PARITY_EVEN 1 +#define PARITY_ODD 2 + +#define FC_NONE 0 +#define FC_XONXOFF 1 +#define FC_RTSCTS 2 + +#define EPOLL_RUN_TIMEOUT -1 +#define MAX_CLIENTS_IN_QUEUE 64 + +#define MAX_EPOLL_EVENTS MAX_CLIENTS_IN_QUEUE + 4 // + timer + listen socket + com-port +#define NUM_OF_DEVICES 8 // num of services (e.g. RS232, RS485 means 2) + +#define MAX_TCP_BUF_SIZE 1024 +#define MAX_SERIAL_BUF_SIZE 4096 + +#define MAX_DIGITS_IN_DEV_NUM 4 // 2+2 nonprinted symbols +#define MAX_CHARS_IN_UCIPATH 128 +#define MAX_INOTIFY_BUF_SIZE 1024 + +#define TMP_PATH_LENGTH 20 +#define DOMAIN_NAME_LENGTH 256 + +#define IMEI_LENGTH 15 + +#define FIRST_RECONN_TIMEOUT 10 + +//MODBUS +#define MAX_PACK_SIZE 300 + +#define MB_TCP_HEADER_SIZE 6 +#define MB_TCP_HEADER_LEN 5 + +#define MB_ASCII_ON 1 + +#define RS485_ON 1 + +typedef struct +{ + int mode; + char deviceName[TMP_PATH_LENGTH]; + int baudRate; + int byteSize; + int parity; + int flowcontrol; + int stopBits; + int serverPort; + int connection_mode; + int holdConnTime; + char clientHost[DOMAIN_NAME_LENGTH]; + int clientPort; + int clientAuth; + int clientTimeout; + long long int clientID; + int modbus_gateway; + int quiet; + int timeout_pack; + int size_pack; + int rs485_mode; +} device_config_t; + + +typedef struct{ + int state; + char header[MB_TCP_HEADER_SIZE]; + char packet[MAX_PACK_SIZE]; + int offset; + int len; + uint8_t crc; +}t_rtu; + +typedef struct{ + char packet[MAX_PACK_SIZE]; + int offset; + int timer; + int state; + int sock; + struct itimerspec newValue; +}t_mb_tcp; + +struct fdStructType +{ + int mainSocket; + int serialPort; + int TCPtimer; + int epollFD; + t_rtu state_rtu; + t_mb_tcp mb_tcp; +}; + +void CleanThread(struct fdStructType *threadFD); +void *ServerThreadFunc(void *args); +void *ClientThreadFunc(void *args); +device_config_t GetFullDeviceConfig(int deviceID); +int FormAuthAnswer(char *dataBuffer, long long int clientID); +uint16_t Crc16Block(uint8_t* block, uint16_t len); +//Modbus +int SendModbusRTU(struct fdStructType *threadFD,char *pBuf, int len, int ascii_rtu, int quiet); +void SendModbusTCP(struct fdStructType *threadFD,char *pBuf, int len, int quiet); +void SendModbusASCIItoTCP(struct fdStructType *threadFD,char *pBuf, int len, uint8_t server, uint8_t connection_mode, int quiet); +void EndTimeoutModbusTCP(struct fdStructType *threadFD, uint8_t server, int ascii_rtu, uint8_t connection_mode, int quiet); +void ClearModbus(struct fdStructType *threadFD); +void send_all(const void *dataBuffer, size_t numOfReadBytes, int flags); + +/*****************************************/ +/*************** MAIN FUNC ***************/ +/*****************************************/ +int main(int argc, char **argv) +{ + pthread_t thread[NUM_OF_DEVICES] = {0}; + pthread_attr_t threadAttr; + pthread_attr_init(&threadAttr); + pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED); + + device_config_t deviceConfig[NUM_OF_DEVICES]; + device_config_t newDeviceConfig; + + int i; + int result; + + + + /* Check devices' settings */ + for(i = 0; i < NUM_OF_DEVICES; i++) + { + // READ ALL UCI CONFIGS -> deviceConfig[i] + deviceConfig[i] = GetFullDeviceConfig(i); + + // ACCODING TO MODE START CLIENT OR SERVER THREAD + if(deviceConfig[i].mode == MODE_SERVER) + { + result = pthread_create(&thread[i], &threadAttr, ServerThreadFunc, (void*) &deviceConfig[i]); + if(result != 0) + LOG("Creating server thread for dev %s false. Error: %d\n", deviceConfig[i].deviceName, result); + else + LOG("Server thread is started for dev %s\n", deviceConfig[i].deviceName); + } + else if (deviceConfig[i].mode == MODE_CLIENT) + { + result = pthread_create(&thread[i], &threadAttr, ClientThreadFunc, (void*) &deviceConfig[i]); + if(result != 0) + LOG("Creating client thread for dev %s false. Error: %d\n", deviceConfig[i].deviceName, result); + else + LOG("Client thread is started for dev %s\n", deviceConfig[i].deviceName); + } + } + + // inotify for parsing changed in /etc/config/pollmydevice + int inotifyFD = inotify_init(); + if(inotifyFD < 0) + { + LOG("Couldn't initialize inotify"); + } + int inotifyWatch = inotify_add_watch(inotifyFD, "/overlay/upper/etc/config/pollmydevice", IN_MODIFY); + if (inotifyWatch < 0) + { + printf("Couldn't add watch to /etc/config/pollmydevice\n"); + } + char inotifyBuf[1024]; + + // epoll for detecting inotify + struct epoll_event epollConfig; + struct epoll_event epollEvent[1]; + int epollFD = epoll_create(sizeof(inotifyFD)); + + epollConfig.events = EPOLLIN | EPOLLET; + epollConfig.data.fd = inotifyFD; + // add our inotify into epoll + result = epoll_ctl(epollFD, EPOLL_CTL_ADD, inotifyFD, &epollConfig); + if(result < 0) + { + LOG("Error while inotify epoll regisration\n"); + } + + + while (1) + { + result = epoll_wait(epollFD, epollEvent, MAX_EPOLL_EVENTS, EPOLL_RUN_TIMEOUT); + + read(inotifyFD, &inotifyBuf, MAX_INOTIFY_BUF_SIZE); + inotifyWatch = inotify_add_watch(inotifyFD, "/overlay/upper/etc/config/pollmydevice", IN_MODIFY); // not working with luci witout it (mystic) + + for(i = 0; i < NUM_OF_DEVICES; i++) + { + // GET SETTINGS + newDeviceConfig = GetFullDeviceConfig(i); + // IF SETTINGS WAS CHANGED + if(memcmp(&newDeviceConfig, deviceConfig+i, sizeof(newDeviceConfig)) != 0) + { + + // IF ANY THREAD IS WORKING ON THIS DERVICE, STOP IT + if(thread[i] != 0) + { + result = pthread_cancel(thread[i]); + thread[i] = 0; + if(result != 0) + { + LOG("Stopping service thread for dev ID %d false. Error: %d\n", i, result); + } else + { + LOG("Service thread is stopped for dev ID %d\n", i); + } + } + + // WRITE NEW CONFIG INTO STRUCT deviceConfig[i] + memcpy(deviceConfig+i, &newDeviceConfig, sizeof(newDeviceConfig)); + + // ACCODING TO MODE START CLIENT OR SERVER THREAD + if(deviceConfig[i].mode == MODE_SERVER) + { + result = pthread_create(&thread[i], &threadAttr, ServerThreadFunc, (void*) &deviceConfig[i]); + + if(result != 0) + LOG("Creating server thread for dev ID %s false. Error: %d\n", deviceConfig[i].deviceName, result); + else + LOG("Server thread is started for dev ID %s\n", deviceConfig[i].deviceName); + } + else if (deviceConfig[i].mode == MODE_CLIENT) + { + result = pthread_create(&thread[i], &threadAttr, ClientThreadFunc, (void*) &deviceConfig[i]); + if(result != 0) + LOG("Creating client thread for dev %s false. Error: %d\n", deviceConfig[i].deviceName, result); + else + LOG("Client thread is started for dev %s\n", deviceConfig[i].deviceName); + } + } + } + } + return 0; +} + + +// When thread close we must close all it's file descriptors +void CleanThread(struct fdStructType *threadFD) +{ + close(threadFD->mainSocket); + close(threadFD->serialPort); + close(threadFD->TCPtimer); + close(threadFD->mb_tcp.timer); + close(threadFD->epollFD); + free(threadFD); + LOG("Descriptors closed\n"); +} +/*****************************************/ +/************* SERVER FUNC ***************/ +/*****************************************/ +void *ServerThreadFunc(void *args) +{ + struct fdStructType *threadFD = malloc(sizeof(struct fdStructType)); + + pthread_cleanup_push(CleanThread, threadFD); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + device_config_t deviceConfig = {0}; + memcpy(&deviceConfig, args, sizeof(device_config_t)); + + int dataBufferSize = MAX_SERIAL_BUF_SIZE; + int listeningServerPort = deviceConfig.serverPort; + + int lastActiveConnSocket = -1, eventSource; + struct sockaddr_in networkAddr; + char dataBuffer[dataBufferSize]; + int numOfReadBytes; + + int blockOther = 0; + int blockSource = -1; + + struct epoll_event epollConfig; + struct epoll_event epollEventArray[MAX_EPOLL_EVENTS]; + + int numOfNewEvents; + int i, result; + uint32_t currentEvents = 0; + + threadFD->epollFD = epoll_create(MAX_EPOLL_EVENTS); + if (threadFD->epollFD < 0) + { + LOG("Error while creating epoll on dev %s \n", deviceConfig.deviceName); + pthread_exit(NULL); + } + + + ///////////////////////// + /**** Listen socket ****/ + ///////////////////////// + + threadFD->mainSocket = socket(AF_INET, SOCK_STREAM, 0); // 0 - default protocol (TCP in this case) + if(threadFD->mainSocket < 0) + { + LOG("Error while creating a listening socket\n"); + pthread_exit(NULL); + } + + networkAddr.sin_family = AF_INET; + networkAddr.sin_port = htons(listeningServerPort); + networkAddr.sin_addr.s_addr = htonl(INADDR_ANY); // receive data from any client address + fcntl(threadFD->mainSocket, F_SETFL, O_NONBLOCK); // set listening socket as nonblocking + + // sometimes in case of programm restart socket can hang, so we have to do this: + int yes = 1; + if (setsockopt(threadFD->mainSocket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1) + { + LOG("Error while setting socket options, errno: %s\n", strerror(errno)); + pthread_exit(NULL); + } + + // bind listening socket with network interface(port,...) + result = bind(threadFD->mainSocket, (struct sockaddr *)&networkAddr, sizeof(networkAddr)); + if(result < 0) + { + LOG("Error while listening socket binding: %d\n", result); + pthread_exit(NULL); + } + + epollConfig.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; + epollConfig.data.fd = threadFD->mainSocket; + // add our listening socket into epoll + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->mainSocket, &epollConfig); + if(result < 0) + { + LOG("Error while listening socket epoll regisration\n"); + pthread_exit(NULL); + } + + + ///////////////////////// + /***** Serial Port *****/ + ///////////////////////// + + struct termios serialPortConfig; + + /// here we must forbid access to serial from other apps + + ///// open serial + threadFD->serialPort = open(deviceConfig.deviceName, O_RDWR | O_NOCTTY); + if (threadFD->serialPort < 0) + { + LOG("Error %d while opening dev %s \n", threadFD->serialPort, deviceConfig.deviceName); + pthread_exit(NULL); + } + + // read config + if (tcgetattr(threadFD->serialPort, &serialPortConfig) != 0) + { + LOG("Error while reading port config %s; errno: %s\n", deviceConfig.deviceName, strerror(errno)); + pthread_exit(NULL); + } + bzero(&serialPortConfig, sizeof(serialPortConfig)); // clear struct for new port settings + + if(deviceConfig.rs485_mode == RS485_ON) + { + struct serial_rs485 rs485conf; + rs485conf.flags |= SER_RS485_ENABLED; + rs485conf.flags |= SER_RS485_RTS_ON_SEND; + rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); + rs485conf.delay_rts_before_send = 0; + rs485conf.delay_rts_after_send = 0; + + if (ioctl(threadFD->serialPort, TIOCSRS485, &rs485conf) < 0) { + LOG("Can not set RS485 mode for %s\n", deviceConfig.deviceName); + } else { + LOG("RS485 mode for %s is successfully set\n", deviceConfig.deviceName); + } + } + + // set config + speed_t newBaudRate; + switch (deviceConfig.baudRate) + { + case 300: newBaudRate = B300 ; break; + case 600: newBaudRate = B600 ; break; + case 1200: newBaudRate = B1200 ; break; + case 1800: newBaudRate = B1800 ; break; + case 2400: newBaudRate = B2400 ; break; + case 4800: newBaudRate = B4800 ; break; + case 9600: newBaudRate = B9600 ; break; + case 19200: newBaudRate = B19200 ; break; + case 38400: newBaudRate = B38400 ; break; + case 57600: newBaudRate = B57600 ; break; + case 115200: newBaudRate = B115200 ; break; + case 230400: newBaudRate = B230400 ; break; + case 460800: newBaudRate = B460800 ; break; + case 921600: newBaudRate = B921600 ; break; + default: newBaudRate = B9600 ; break; + } + + serialPortConfig.c_cflag = newBaudRate | CLOCAL | CREAD; // Enable the receiver and set local mode, 8n1 ??? + + // set parity + if(deviceConfig.parity == PARITY_EVEN) + { + serialPortConfig.c_cflag |= PARENB; + } + else if(deviceConfig.parity == PARITY_ODD) + { + serialPortConfig.c_cflag |= PARENB; + serialPortConfig.c_cflag |= PARODD; + } + + // set flow control + if(deviceConfig.flowcontrol == FC_RTSCTS) + { + serialPortConfig.c_cflag |= CRTSCTS; + } + else if(deviceConfig.flowcontrol == FC_XONXOFF) + { + serialPortConfig.c_iflag |= (IXON | IXOFF | IXANY); + } + + if(deviceConfig.stopBits == 2) + serialPortConfig.c_cflag |= CSTOPB; + + // set bytesize + if(deviceConfig.byteSize == 8) serialPortConfig.c_cflag |= CS8; + else if(deviceConfig.byteSize == 7) serialPortConfig.c_cflag |= CS7; + else if(deviceConfig.byteSize == 6) serialPortConfig.c_cflag |= CS6; + else if(deviceConfig.byteSize == 5) serialPortConfig.c_cflag |= CS5; + else serialPortConfig.c_cflag |= CS8; + + //serialPortConfig.c_cc[VMIN] = 0; // blocking read until 1 character arrives (0 - no, 1 - yes) + //serialPortConfig.c_cc[VTIME] = 0; // inter-character timer + + unsigned char val = (uint8_t)((deviceConfig.timeout_pack)%256); + serialPortConfig.c_line &= ~ICANON; //DISABLE CANONCIAL + serialPortConfig.c_cc[VTIME] = val; // inter-character timer + LOG("Set VTIME=%d\n", val); + val = (uint8_t)(deviceConfig.size_pack%256); + serialPortConfig.c_cc[VMIN] = val; // blocking read until 1 character arrives (0 - no, 1 - yes) + LOG("Set VMIN=%d\n", val); + + // write config + tcflush(threadFD->serialPort, TCIFLUSH); // clean the line + tcsetattr(threadFD->serialPort, TCSANOW, &serialPortConfig); // change config right now (may be TCSADRAIN,TCSAFLUSH) + + // add serial port fd to epoll + epollConfig.data.fd = threadFD->serialPort; + epollConfig.events = EPOLLIN | EPOLLET; // message, edge trigger + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->serialPort, &epollConfig); + if(result < 0) + { + LOG("Error while serial port epoll regisration\n"); + pthread_exit(NULL); + } + + ///////////////////////// + /**** Timer for TCP ****/ + ///////////////////////// + + int holdConnTime = deviceConfig.holdConnTime; + struct itimerspec newValue; + struct itimerspec oldValue; + bzero(&newValue,sizeof(newValue)); + bzero(&oldValue,sizeof(oldValue)); + + struct timespec ts; + ts.tv_sec = holdConnTime; + ts.tv_nsec = 0; + newValue.it_value = ts; + + threadFD->TCPtimer = timerfd_create(CLOCK_MONOTONIC,TFD_NONBLOCK); + if(threadFD->TCPtimer < 0) + { + LOG("Error while timerfd create \n"); + pthread_exit(NULL); + } + + // add timer fd to epoll + epollConfig.events = EPOLLIN | EPOLLET; + epollConfig.data.fd = threadFD->TCPtimer; + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->TCPtimer, &epollConfig); + if(result < 0) + { + LOG("Epoll timer addition error\n"); + pthread_exit(NULL); + } + //////////////////////////// + /** Timer for TCP MODBUS **/ + //////////////////////////// + ClearModbus(threadFD); + int pack_timeout; + if(deviceConfig.baudRate > 19200){ //calculating timeout between package for MODBUS protocol + pack_timeout = 1750; + }else{ + pack_timeout = 35000000/deviceConfig.baudRate; + } + bzero(&threadFD->mb_tcp.newValue,sizeof(struct itimerspec)); + threadFD->mb_tcp.newValue.it_value.tv_sec = 0; + threadFD->mb_tcp.newValue.it_value.tv_nsec = pack_timeout*1000*10; + + threadFD->mb_tcp.timer = timerfd_create(CLOCK_MONOTONIC,TFD_NONBLOCK); + if(threadFD->mb_tcp.timer < 0){ + LOG("Error while timerfd for TCP MODBUS create \n"); + pthread_exit(NULL); + } + // add modbus tcp timer fd to epoll + epollConfig.events = EPOLLIN | EPOLLET; + epollConfig.data.fd = threadFD->mb_tcp.timer; + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->mb_tcp.timer, &epollConfig); + if(result < 0) + { + LOG("Error while timer epoll regisration\n"); + pthread_exit(NULL); + } + + // begin waiting for clients + listen(threadFD->mainSocket, MAX_CLIENTS_IN_QUEUE); + LOG("Listening on dev %s port %d\n", deviceConfig.deviceName, listeningServerPort); + + while(1) + { + numOfNewEvents = epoll_wait(threadFD->epollFD, epollEventArray, MAX_EPOLL_EVENTS, EPOLL_RUN_TIMEOUT); + + for(i = 0; i < numOfNewEvents; i++) + { + eventSource = epollEventArray[i].data.fd; + currentEvents = epollEventArray[i].events; + + // if we have a new connection + if(eventSource == threadFD->mainSocket) + { + result = accept(threadFD->mainSocket, NULL, NULL); // we don't care about a client address + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while accepting connection\n"); + } + else + lastActiveConnSocket = result; + + fcntl(lastActiveConnSocket, F_SETFL, O_NONBLOCK); // set listening socket as nonblocking + if (!deviceConfig.quiet) + LOG("New incoming connection\n"); + + epollConfig.data.fd = lastActiveConnSocket; + epollConfig.events = EPOLLIN | EPOLLET; // message, edge trigger + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, lastActiveConnSocket, &epollConfig); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Epoll connection addition error %d\n", result); + } else { + if(deviceConfig.connection_mode == 1) + { + client_insert(lastActiveConnSocket); + } + } + } + + // data from serial + else if(eventSource == threadFD->serialPort) + { + numOfReadBytes = read(threadFD->serialPort, dataBuffer, dataBufferSize); + if(deviceConfig.modbus_gateway){ + if(deviceConfig.modbus_gateway == 2){ + if (!deviceConfig.quiet) + LOG("Receive modbus ASCII data %d\n", numOfReadBytes); + threadFD->mb_tcp.sock = lastActiveConnSocket; + SendModbusASCIItoTCP(threadFD, dataBuffer, numOfReadBytes, 1, deviceConfig.connection_mode, deviceConfig.quiet); + }else{ + if (!deviceConfig.quiet) + LOG("Receive modbus RTU data %d\n", numOfReadBytes); + SendModbusTCP(threadFD, dataBuffer, numOfReadBytes, deviceConfig.quiet); + } + }else{ + if(deviceConfig.connection_mode == 0) + { + result=send(lastActiveConnSocket, dataBuffer, numOfReadBytes, MSG_NOSIGNAL); + if (!result) { + LOG("Error %d while sending data, close connection\n", result); + } + } else { + send_all(dataBuffer, numOfReadBytes, MSG_NOSIGNAL); + } + } + }else + // timer modbus tcp for forming packets + if(eventSource == threadFD->mb_tcp.timer){ + threadFD->mb_tcp.sock = lastActiveConnSocket; + EndTimeoutModbusTCP(threadFD, 1, deviceConfig.modbus_gateway, deviceConfig.connection_mode, deviceConfig.quiet); + } + + else if(eventSource == threadFD->TCPtimer) + { + if(deviceConfig.connection_mode == 0) + { + blockOther = 0; // free access for all clients + LOG("Connection hold time is up. Free access for all clients\n"); + } + } + + // data from TCP on existing connection + else if(currentEvents & EPOLLIN) + { + numOfReadBytes = recv(eventSource, dataBuffer, dataBufferSize, 0); + if(numOfReadBytes > 0) + { + // if block source sent data or block is disabled, we handle it + if(blockOther == 0 || blockSource == eventSource) + { + // close access for other untill (last activity timer will signalize) or (our TCP will close) + + blockSource = eventSource; + if(deviceConfig.connection_mode == 0){ + blockOther = 1; + result = timerfd_settime(threadFD->TCPtimer, 0, &newValue, &oldValue); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while timer setup \n"); + } + } + dataBuffer[numOfReadBytes] = 0; + if(!deviceConfig.modbus_gateway){ + write(threadFD->serialPort, dataBuffer, numOfReadBytes); + lastActiveConnSocket = eventSource; + }else + if(!SendModbusRTU(threadFD, dataBuffer, numOfReadBytes, deviceConfig.modbus_gateway, deviceConfig.quiet)){ + close(eventSource); + epollConfig.data.fd = eventSource; + epoll_ctl(threadFD->epollFD, EPOLL_CTL_DEL, eventSource, &epollConfig); + // if block source wanted to close connection, we free access for all + if(blockSource == eventSource) + { + blockOther = 0; // free access for all clients + } + if (!deviceConfig.quiet) + LOG("Connection closed\n"); + lastActiveConnSocket = -1; + }else lastActiveConnSocket = eventSource; + } + else + if (!deviceConfig.quiet) + LOG("Data refused\n"); + //lastActiveConnSocket = -1; + } + else // if someone want to close connection + { + close(eventSource); + epollConfig.data.fd = eventSource; + epoll_ctl(threadFD->epollFD, EPOLL_CTL_DEL, eventSource, &epollConfig); + if(deviceConfig.connection_mode == 1) + { + remove_descr(eventSource); + } + // if block source wanted to close connection, we free access for all + if(blockSource == eventSource) + { + blockOther = 0; // free access for all clients + } + if (!deviceConfig.quiet) + LOG("Connection closed\n"); + lastActiveConnSocket = -1; + } + } + + else + { + if (!deviceConfig.quiet) + LOG("Unknown epoll event\n"); + //lastActiveConnSocket = -1; + } + } + } + + pthread_cleanup_pop(1); + return (void *) 0; +} + + + +/*****************************************/ +/************* CLIENT FUNC ***************/ +/*****************************************/ +void *ClientThreadFunc(void *args) +{ + struct fdStructType *threadFD = malloc(sizeof(struct fdStructType)); + + pthread_cleanup_push(CleanThread, threadFD); + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + device_config_t deviceConfig = {0}; + memcpy(&deviceConfig, args, sizeof(device_config_t)); + + int dataBufferSize = MAX_SERIAL_BUF_SIZE; + + int eventSource; + + char dataBuffer[dataBufferSize]; + const char authRequest[28] = "\xC0\x00\x06\x00\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xE7\x48\xC2"; + const char authAcknow[28] = "\xC0\x00\x06\x01\x14\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3F\x25\xC2"; + int numOfReadBytes; + + int serverAvailable = 0, autorized = 0; + int stat = 0; + + struct epoll_event epollConfig; + struct epoll_event epollEventArray[MAX_EPOLL_EVENTS]; + + int numOfNewEvents; + int i, result; + + ///////////////////////// + /***** Serial Port *****/ + ///////////////////////// + struct termios serialPortConfig; + /// here we must forbid access to serial from other apps + + // open serial + threadFD->serialPort = open(deviceConfig.deviceName, O_RDWR | O_NOCTTY); + if (threadFD->serialPort < 0) + { + LOG("Error %d while opening dev %s \n", threadFD->serialPort, deviceConfig.deviceName); + pthread_exit(NULL); + } + + // read config + if (tcgetattr(threadFD->serialPort, &serialPortConfig) != 0) + { + LOG("Error while reading port config %s", deviceConfig.deviceName); + pthread_exit(NULL); + } + bzero(&serialPortConfig, sizeof(serialPortConfig)); // clear struct for new port settings + + if(deviceConfig.rs485_mode == RS485_ON) + { + struct serial_rs485 rs485conf; + rs485conf.flags |= SER_RS485_ENABLED; + rs485conf.flags |= SER_RS485_RTS_ON_SEND; + rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); + rs485conf.delay_rts_before_send = 0; + rs485conf.delay_rts_after_send = 0; + + if (ioctl(threadFD->serialPort, TIOCSRS485, &rs485conf) < 0) { + LOG("Can not set RS485 mode for %s", deviceConfig.deviceName); + } else { + LOG("RS485 mode for %s is successfully set", deviceConfig.deviceName); + } + } + + // set config + speed_t newBaudRate; + switch (deviceConfig.baudRate) + { + case 300: newBaudRate = B300 ; break; + case 600: newBaudRate = B600 ; break; + case 1200: newBaudRate = B1200 ; break; + case 1800: newBaudRate = B1800 ; break; + case 2400: newBaudRate = B2400 ; break; + case 4800: newBaudRate = B4800 ; break; + case 9600: newBaudRate = B9600 ; break; + case 19200: newBaudRate = B19200 ; break; + case 38400: newBaudRate = B38400 ; break; + case 57600: newBaudRate = B57600 ; break; + case 115200: newBaudRate = B115200 ; break; + case 230400: newBaudRate = B230400 ; break; + case 460800: newBaudRate = B460800 ; break; + case 921600: newBaudRate = B921600 ; break; + default: newBaudRate = B9600 ; break; + } + + serialPortConfig.c_cflag = newBaudRate | CLOCAL | CREAD; // Enable the receiver and set local mode, 8n1 ??? + + // set parity + if(deviceConfig.parity == PARITY_EVEN) + { + serialPortConfig.c_cflag |= PARENB; + } + else if(deviceConfig.parity == PARITY_ODD) + { + serialPortConfig.c_cflag |= PARENB; + serialPortConfig.c_cflag |= PARODD; + } + + // set flow control + if(deviceConfig.flowcontrol == FC_RTSCTS) + { + serialPortConfig.c_cflag |= CRTSCTS; + } + else if(deviceConfig.flowcontrol == FC_XONXOFF) + { + serialPortConfig.c_iflag |= (IXON | IXOFF | IXANY); + } + + if(deviceConfig.stopBits == 2) + serialPortConfig.c_cflag |= CSTOPB; + + // set bytesize + if(deviceConfig.byteSize == 8) serialPortConfig.c_cflag |= CS8; + else if(deviceConfig.byteSize == 7) serialPortConfig.c_cflag |= CS7; + else if(deviceConfig.byteSize == 6) serialPortConfig.c_cflag |= CS6; + else if(deviceConfig.byteSize == 5) serialPortConfig.c_cflag |= CS5; + else serialPortConfig.c_cflag |= CS8; + +// serialPortConfig.c_cc[VMIN] = 0; // blocking read until 1 character arrives (0 - no, 1 - yes) +// serialPortConfig.c_cc[VTIME] = 0; // inter-character timer + + unsigned char val = (uint8_t)((deviceConfig.timeout_pack)%256); + serialPortConfig.c_line &= ~ICANON; //DISABLE CANONCIAL + serialPortConfig.c_cc[VTIME] = val; // inter-character timer + val = (uint8_t)(deviceConfig.size_pack%256); + serialPortConfig.c_cc[VMIN] = val; // blocking read until 1 character arrives (0 - no, 1 - yes) + + // write config + tcflush(threadFD->serialPort, TCIFLUSH); // clean the line + tcsetattr(threadFD->serialPort, TCSANOW, &serialPortConfig); // change config right now (may be TCSADRAIN,TCSAFLUSH) + + + ///////////////////////// + /**** Timer for TCP ****/ + ///////////////////////// + int clientTimeout = deviceConfig.clientTimeout; + struct itimerspec newValue; + struct itimerspec oldValue; + bzero(&newValue,sizeof(newValue)); + bzero(&oldValue,sizeof(oldValue)); + + struct timespec ts; + ts.tv_sec = clientTimeout; + ts.tv_nsec = 0; + newValue.it_value = ts; + + threadFD->TCPtimer = timerfd_create(CLOCK_MONOTONIC,TFD_NONBLOCK); + if(threadFD->TCPtimer < 0) + { + LOG("Error while timerfd create \n"); + pthread_exit(NULL); + } + + //////////////////////////// + /** Timer for TCP MODBUS **/ + //////////////////////////// + ClearModbus(threadFD); + int pack_timeout; + if(deviceConfig.baudRate > 19200){ //calculating timeout between package for MODBUS protocol + pack_timeout = 1750; + }else{ + pack_timeout = 35000000/deviceConfig.baudRate; + } + bzero(&threadFD->mb_tcp.newValue,sizeof(struct itimerspec)); + threadFD->mb_tcp.newValue.it_value.tv_sec = 0; + threadFD->mb_tcp.newValue.it_value.tv_nsec = pack_timeout*1000*10; + LOG("Timer set = %lu \n",threadFD->mb_tcp.newValue.it_value.tv_nsec); + + threadFD->mb_tcp.timer = timerfd_create(CLOCK_MONOTONIC,TFD_NONBLOCK); + if(threadFD->mb_tcp.timer < 0){ + LOG("Error while timerfd for TCP MODBUS create \n"); + pthread_exit(NULL); + } + + + + ///////////////////////// + /** Connect To Server **/ + ///////////////////////// + struct sockaddr_in addr; + struct hostent *server; + + LOG("Trying to connect... \n"); + while(1) + { + server = gethostbyname(deviceConfig.clientHost); + if (server == NULL) + { + if (!deviceConfig.quiet) + LOG("Error while resolving %s\n", deviceConfig.clientHost); + sleep(FIRST_RECONN_TIMEOUT); + continue; + } + + // server's internet address + bzero((char *) &addr, sizeof(addr)); + addr.sin_family = AF_INET; + bcopy((char *)server->h_addr, (char *)&addr.sin_addr.s_addr, server->h_length); + addr.sin_port = htons(deviceConfig.clientPort); + + threadFD->mainSocket = socket(AF_INET, SOCK_STREAM, 0); + if(threadFD->mainSocket < 0) + { + if (!deviceConfig.quiet) + LOG("Error while creating client socket \n"); + sleep(FIRST_RECONN_TIMEOUT); + continue; + } + + result = connect(threadFD->mainSocket, (struct sockaddr *)&addr, sizeof(addr)); + if(result == 0) + { + if (!deviceConfig.quiet) + LOG("Client connected successfully \n"); + serverAvailable = 1; + if(timerfd_settime(threadFD->TCPtimer, 0, &newValue, &oldValue) < 0) + { + if (!deviceConfig.quiet) + LOG("Error while timer setup \n"); + } + break; + } + else + { + if (!deviceConfig.quiet) + LOG("Couldn't connect. Retry after %d sec \n", FIRST_RECONN_TIMEOUT); + sleep(FIRST_RECONN_TIMEOUT); + } + } + + + ///////////////////////// + /** Add All To Epoll **/ + ///////////////////////// + threadFD->epollFD = epoll_create(MAX_EPOLL_EVENTS); + if (threadFD->epollFD < 0) + { + LOG("Error while creating epoll on dev %s \n", deviceConfig.deviceName); + pthread_exit(NULL); + } + // add timer fd to epoll + epollConfig.events = EPOLLIN | EPOLLET; + epollConfig.data.fd = threadFD->TCPtimer; + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->TCPtimer, &epollConfig); + if(result < 0) + { + LOG("Error while timer epoll regisration\n"); + pthread_exit(NULL); + } + // add modbus tcp timer fd to epoll + epollConfig.events = EPOLLIN | EPOLLET; + epollConfig.data.fd = threadFD->mb_tcp.timer; + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->mb_tcp.timer, &epollConfig); + if(result < 0) + { + LOG("Error while timer epoll regisration\n"); + pthread_exit(NULL); + } + // add serial port fd to epoll + epollConfig.events = EPOLLIN | EPOLLET; // message, edge trigger + epollConfig.data.fd = threadFD->serialPort; + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->serialPort, &epollConfig); + if(result < 0) + { + LOG("Error while serial port epoll regisration\n"); + pthread_exit(NULL); + } + // add socket fd to epoll + epollConfig.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; + epollConfig.data.fd = threadFD->mainSocket; + // add socket into epoll + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->mainSocket, &epollConfig); + if(result < 0) + { + LOG("Error while socket epoll regisration\n"); + pthread_exit(NULL); + } + + + while(1) + { + numOfNewEvents = epoll_wait(threadFD->epollFD, epollEventArray, MAX_EPOLL_EVENTS, EPOLL_RUN_TIMEOUT); + + for(i = 0; i < numOfNewEvents; i++) + { + eventSource = epollEventArray[i].data.fd; + + // data from TCP connection + if(eventSource == threadFD->mainSocket) + { + numOfReadBytes = recv(eventSource, dataBuffer, dataBufferSize, 0); + //LOG("incoming %d bytes\n", numOfReadBytes); + if(numOfReadBytes > 0) // in case of normal packet + { + // if we are autorized already OR we don't need autorization + if(autorized == 1 || deviceConfig.clientAuth == 0) + { + //TODO SETTING MODBUS + if(!deviceConfig.modbus_gateway){ + write(threadFD->serialPort, dataBuffer, numOfReadBytes); + }else + if(!SendModbusRTU(threadFD, dataBuffer, numOfReadBytes, deviceConfig.modbus_gateway, deviceConfig.quiet)){ + // close existing connection + close(eventSource); + // remove from epoll + epollConfig.data.fd = eventSource; + epoll_ctl(threadFD->epollFD, EPOLL_CTL_DEL, eventSource, &epollConfig); + if (!deviceConfig.quiet) + LOG("Connection closed\n"); + + serverAvailable = 0; + autorized = 0; + // re-create socket + threadFD->mainSocket = socket(AF_INET, SOCK_STREAM, 0); + if(threadFD->mainSocket < 0) + { + if (!deviceConfig.quiet) + LOG("Error while re-opening client socket \n"); + } + + // add to epoll again + epollConfig.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; + epollConfig.data.fd = threadFD->mainSocket; + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->mainSocket, &epollConfig); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while socket epoll regisration\n"); + pthread_exit(NULL); + } + + result = connect(threadFD->mainSocket, (struct sockaddr *)&addr, sizeof(addr)); + + // if connection is not successfull, restart timer + if(result != 0) + { + result = timerfd_settime(threadFD->TCPtimer, 0, &newValue, &oldValue); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while timer setup \n"); + } + } + else + { + if (!deviceConfig.quiet) + LOG("Client re-connected successfully \n"); + serverAvailable = 1; + } + } + //LOG("TCP -> Serial: %d bytes\n", numOfReadBytes); + result = timerfd_settime(threadFD->TCPtimer, 0, &newValue, &oldValue); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while timer setup \n"); + } + } + else + { + // if it is an autorization request from server + if (numOfReadBytes == 28) + { + if(memcmp(dataBuffer, authRequest, 28) == 0) + { + if (!deviceConfig.quiet) + LOG("Autorization request from server\n"); + numOfReadBytes = FormAuthAnswer(dataBuffer, deviceConfig.clientID); + result=send(threadFD->mainSocket, dataBuffer, numOfReadBytes, MSG_NOSIGNAL); // maybe add some check??? + if (!result) { + LOG("Error %d while sending data\n", result); + } + dataBuffer[numOfReadBytes] = 0; + } + else if(memcmp(dataBuffer, authAcknow, 28) == 0) + { + autorized = 1; + if (!deviceConfig.quiet) + LOG("Autorization OK \n"); + } + else // error, reconnect + { + if (!deviceConfig.quiet) + LOG("Autorization ERROR. Reconnect... \n"); + + // close existing connection + close(eventSource); + // remove from epoll + epollConfig.data.fd = eventSource; + epoll_ctl(threadFD->epollFD, EPOLL_CTL_DEL, eventSource, &epollConfig); + if (!deviceConfig.quiet) + LOG("Connection closed by server\n"); + + serverAvailable = 0; + autorized = 0; + // re-create socket + threadFD->mainSocket = socket(AF_INET, SOCK_STREAM, 0); + if(threadFD->mainSocket < 0) + { + if (!deviceConfig.quiet) + LOG("Error while re-opening client socket \n"); + } + + // add to epoll again + epollConfig.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; + epollConfig.data.fd = threadFD->mainSocket; + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->mainSocket, &epollConfig); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while socket epoll regisration\n"); + pthread_exit(NULL); + } + + result = connect(threadFD->mainSocket, (struct sockaddr *)&addr, sizeof(addr)); + + // if connection is not successfull, restart timer + if(result != 0) + { + result = timerfd_settime(threadFD->TCPtimer, 0, &newValue, &oldValue); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while timer setup \n"); + } + } + else + { + if (!deviceConfig.quiet) + LOG("Client re-connected successfully \n"); + serverAvailable = 1; + } + } + } + else // error, reconnect + { + if (!deviceConfig.quiet) + LOG("Autorization ERROR. Reconnect... \n"); + + // close existing connection + close(eventSource); + // remove from epoll + epollConfig.data.fd = eventSource; + epoll_ctl(threadFD->epollFD, EPOLL_CTL_DEL, eventSource, &epollConfig); + if (!deviceConfig.quiet) + LOG("Connection closed by server\n"); + + serverAvailable = 0; + autorized = 0; + // re-create socket + threadFD->mainSocket = socket(AF_INET, SOCK_STREAM, 0); + if(threadFD->mainSocket < 0) + { + if (!deviceConfig.quiet) + LOG("Error while re-opening client socket \n"); + } + + // add to epoll again + epollConfig.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; + epollConfig.data.fd = threadFD->mainSocket; + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->mainSocket, &epollConfig); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while socket epoll regisration\n"); + pthread_exit(NULL); + } + + result = connect(threadFD->mainSocket, (struct sockaddr *)&addr, sizeof(addr)); + + // if connection is not successfull, restart timer + if(result != 0) + { + result = timerfd_settime(threadFD->TCPtimer, 0, &newValue, &oldValue); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while timer setup \n"); + } + } + else + { + if (!deviceConfig.quiet) + LOG("Client re-connected successfully \n"); + serverAvailable = 1; + } + } + } + } + else // if server wants to close connection + { + // close existing connection + close(eventSource); + // remove from epoll + epollConfig.data.fd = eventSource; + epoll_ctl(threadFD->epollFD, EPOLL_CTL_DEL, eventSource, &epollConfig); + if (stat == 0) + if (!deviceConfig.quiet) + LOG("Connection closed by server\n"); + stat = 1; + + serverAvailable = 0; + autorized = 0; + // re-create socket + threadFD->mainSocket = socket(AF_INET, SOCK_STREAM, 0); + if(threadFD->mainSocket < 0) + { + if (!deviceConfig.quiet) + LOG("Error while re-opening client socket \n"); + } + + // add to epoll again + epollConfig.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; + epollConfig.data.fd = threadFD->mainSocket; + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->mainSocket, &epollConfig); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while socket epoll regisration\n"); + pthread_exit(NULL); + } + + result = connect(threadFD->mainSocket, (struct sockaddr *)&addr, sizeof(addr)); + + // if connection is not successfull, restart timer + if(result != 0) + { + result = timerfd_settime(threadFD->TCPtimer, 0, &newValue, &oldValue); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while timer setup \n"); + } + } + else + { + if (!deviceConfig.quiet) + LOG("Client re-connected successfully \n"); + serverAvailable = 1; + stat = 0; + } + + } + } + + // data from serial + else if(eventSource == threadFD->serialPort) + { + numOfReadBytes = read(threadFD->serialPort, dataBuffer, dataBufferSize); + if(serverAvailable == 1){ + //TODO SETTING MODBUS + if(deviceConfig.modbus_gateway == 1){ + SendModbusTCP(threadFD, dataBuffer, numOfReadBytes, deviceConfig.quiet); + }else + if(deviceConfig.modbus_gateway == 2){ + threadFD->mb_tcp.sock = threadFD->mainSocket; + SendModbusASCIItoTCP(threadFD, dataBuffer, numOfReadBytes, 0, deviceConfig.connection_mode, deviceConfig.quiet); + }else { + result=send(threadFD->mainSocket, dataBuffer, numOfReadBytes, MSG_NOSIGNAL); + if (!result) { + LOG("Error %d while sending data\n", result); + } + } + } + //LOG("Serial -> TCP: %d bytes\n", numOfReadBytes); + } + + // it's time to reconnect + else if(eventSource == threadFD->TCPtimer) + { + if (!deviceConfig.quiet) + LOG("Time to reconnect\n"); // !!! + + // close existing connection + close(threadFD->mainSocket); + // remove from epoll + epollConfig.data.fd = threadFD->mainSocket; + epoll_ctl(threadFD->epollFD, EPOLL_CTL_DEL, threadFD->mainSocket, &epollConfig); + serverAvailable = 0; + autorized = 0; + + // reconnect + threadFD->mainSocket = socket(AF_INET, SOCK_STREAM, 0); + if(threadFD->mainSocket < 0) + { + if (!deviceConfig.quiet) + LOG("Error while re-opening client socket \n"); + } + + // add to epoll again + epollConfig.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP; + epollConfig.data.fd = threadFD->mainSocket; + result = epoll_ctl(threadFD->epollFD, EPOLL_CTL_ADD, threadFD->mainSocket, &epollConfig); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while socket epoll regisration\n"); + pthread_exit(NULL); + } + + result = connect(threadFD->mainSocket, (struct sockaddr *)&addr, sizeof(addr)); + if(result != 0) + { + if (!deviceConfig.quiet) + LOG("Client re-connection failure\n"); // !!! + } + else + { + if (!deviceConfig.quiet) + LOG("Client re-connected successfully \n"); // !!! + serverAvailable = 1; + } + + // restart timer + result = timerfd_settime(threadFD->TCPtimer, 0, &newValue, &oldValue); + if(result < 0) + { + if (!deviceConfig.quiet) + LOG("Error while timer setup \n"); + } + } else + // timer modbus tcp for forming packets + if(eventSource == threadFD->mb_tcp.timer){ + threadFD->mb_tcp.sock = threadFD->mainSocket; + EndTimeoutModbusTCP(threadFD, 0, deviceConfig.modbus_gateway, deviceConfig.connection_mode, deviceConfig.quiet); + } + + else + { + if (!deviceConfig.quiet) + LOG("Unknown epoll event\n"); + } + } + } + + pthread_cleanup_pop(1); + return (void *) 0; +} + +char ByteToASCII(char x) { + x &= 0x0F; + if (x <= 9) return x + '0'; + return x - 10 + 'A'; +} + + +int SendModbusRTU(struct fdStructType *threadFD,char *pBuf, int len, int ascii_rtu, int quiet){ + + int count=0; + if(threadFD == NULL || pBuf == NULL || !len)return 0; + if(len > MAX_PACK_SIZE) return 0; + + while(count < len){ + switch(threadFD->state_rtu.state){ + case 0: //Init; + threadFD->state_rtu.len = 0; + threadFD->state_rtu.offset = 0; + memset(threadFD->state_rtu.packet, 0, MAX_PACK_SIZE); + memset(threadFD->state_rtu.header, 0, MB_TCP_HEADER_SIZE); + threadFD->state_rtu.state = 1; + break; + case 1: //receive MBAP Header + threadFD->state_rtu.header[threadFD->state_rtu.offset++] = pBuf[count++]; + if(threadFD->state_rtu.offset >= MB_TCP_HEADER_SIZE){ + threadFD->state_rtu.len = threadFD->state_rtu.header[5]; + if (!quiet) + LOG("Receive TCP modbus header len = %d\n", threadFD->state_rtu.len); + if(threadFD->state_rtu.len > MAX_PACK_SIZE || modbus_check_header(threadFD->state_rtu.header)){ + if (!quiet) + LOG("Header is damaged, drop connection\n"); + threadFD->state_rtu.state = 0; + return 0; + } + + if(ascii_rtu == 2){ + threadFD->state_rtu.offset = 1; + threadFD->state_rtu.packet[0] = ':'; + threadFD->state_rtu.crc = 0; + threadFD->state_rtu.state = 3; + }else{ + threadFD->state_rtu.offset = 0; + threadFD->state_rtu.state = 2; + } + } + break; + case 2: //forming RTU packet + threadFD->state_rtu.packet[threadFD->state_rtu.offset++] = pBuf[count++]; + if(threadFD->state_rtu.offset >= threadFD->state_rtu.len){ + modbus_crc_write((unsigned char *)threadFD->state_rtu.packet, threadFD->state_rtu.offset); + if (!quiet) + LOG("Forming RTU modbus packet CRC\n", threadFD->state_rtu.len); + threadFD->state_rtu.offset += 2; + write(threadFD->serialPort, threadFD->state_rtu.packet, threadFD->state_rtu.offset); + if (!quiet) + LOG("Send RTU modbus packet len = %d\n", threadFD->state_rtu.offset); + threadFD->state_rtu.state = 0; + } + break; + case 3: //forming ASCII packet + threadFD->state_rtu.crc += pBuf[count]; + threadFD->state_rtu.packet[threadFD->state_rtu.offset++] = ByteToASCII(pBuf[count]>> 4); + threadFD->state_rtu.packet[threadFD->state_rtu.offset++] = ByteToASCII(pBuf[count++]); + if(threadFD->state_rtu.offset >= ((threadFD->state_rtu.len*2)+1)){ + if (!quiet) + LOG("Forming ASCII modbus packet CRC\n"); + threadFD->state_rtu.crc = (255 - threadFD->state_rtu.crc) + 1; + threadFD->state_rtu.packet[threadFD->state_rtu.offset++] = ByteToASCII(threadFD->state_rtu.crc>> 4); + threadFD->state_rtu.packet[threadFD->state_rtu.offset++] = ByteToASCII(threadFD->state_rtu.crc); + threadFD->state_rtu.packet[threadFD->state_rtu.offset++] = 0x0D; + threadFD->state_rtu.packet[threadFD->state_rtu.offset++] = 0x0A; + write(threadFD->serialPort, threadFD->state_rtu.packet, threadFD->state_rtu.offset); + if (!quiet) + LOG("Send modbus ASCII packet len = %d\n", threadFD->state_rtu.offset); + threadFD->state_rtu.state = 0; + } + break; + } + } + threadFD->state_rtu.state = 0; + return 1; +} +char ASCIItoOctet(char byte){ + if((byte >= '0' && byte <= '9')){ + return (byte-'0'); + }else + if(byte >= 'A' && byte <= 'F'){ + return (byte-'A'+10); + } + return 0; +} +void ClearModbus(struct fdStructType *threadFD){ + + if(threadFD == NULL)return; + + bzero(&threadFD->state_rtu,sizeof(t_rtu)); + bzero(&threadFD->mb_tcp, sizeof(t_mb_tcp)); +} +void InsertByteModbusTCP(t_mb_tcp *pTCP, char symbole){ + int count; + if(pTCP == NULL)return; + count = pTCP->offset + MB_TCP_HEADER_SIZE; + pTCP->packet[count] = symbole; + pTCP->offset++; + return; +} +void SendModbusASCIItoTCP(struct fdStructType *threadFD,char *pBuf, int len, uint8_t server, uint8_t connection_mode, int quiet){ + int count=0; + uint32_t i; + uint8_t calculate_crc=0; + struct itimerspec oldValue; + int result; + + if(threadFD == NULL || pBuf == NULL || !len)return; + if(len > MAX_PACK_SIZE) return; + + t_mb_tcp *pTCP= &threadFD->mb_tcp; + + while(count < len){ + switch(pTCP->state){ + case 0: + if(pBuf[count] == ':'){ + pTCP->state = 1; + pTCP->offset = 0; + bzero( pTCP->packet, MAX_PACK_SIZE); + if (!quiet) + LOG("Start receive modbus ASCII packet"); + } + break; + case 1: + if((pBuf[count] >= '0' && pBuf[count] <= '9') || (pBuf[count] >= 'A' && pBuf[count] <= 'F') ){ + pTCP->packet[pTCP->offset+MB_TCP_HEADER_SIZE] = ASCIItoOctet(pBuf[count]); + pTCP->state = 2; + }else + if(pBuf[count] == 0x0D){ + if(pTCP->offset < 2)pTCP->state = 0; + pTCP->state = 3; + }else{ + pTCP->state = 0; + } + break; + case 2: + if((pBuf[count] >= '0' && pBuf[count] <= '9') || (pBuf[count] >= 'A' && pBuf[count] <= 'F') ){ + pTCP->packet[pTCP->offset+MB_TCP_HEADER_SIZE] = (pTCP->packet[pTCP->offset+MB_TCP_HEADER_SIZE]<<4) | ASCIItoOctet(pBuf[count]); + pTCP->offset++; + if(pTCP->offset >= MAX_PACK_SIZE){ + pTCP->state = 0; + }else{ + pTCP->state = 1; + } + }else{ + pTCP->state = 0; + } + break; + case 3: + if(pBuf[count] == 0x0A){ + pTCP->state = 0; + calculate_crc = 0; + for(i=0;i < (pTCP->offset+MB_TCP_HEADER_SIZE-1);i++){ + calculate_crc += (uint8_t)pTCP->packet[i]; + } + calculate_crc = (255 - calculate_crc) + 1; + if (!quiet) + LOG("Check CRC pack/ Device CRC= %d, calculating CRC=%d\n",(uint8_t)pTCP->packet[pTCP->offset+MB_TCP_HEADER_SIZE-1], calculate_crc); + if(calculate_crc == (uint8_t)pTCP->packet[pTCP->offset+MB_TCP_HEADER_SIZE-1]){ + pTCP->offset--; + memcpy(pTCP->packet,threadFD->state_rtu.header, MB_TCP_HEADER_SIZE); + pTCP->packet[MB_TCP_HEADER_LEN] = (uint8_t)pTCP->offset; + if(server) + { + if(connection_mode == 0) + { + result=send(pTCP->sock, pTCP->packet, pTCP->offset + MB_TCP_HEADER_SIZE, MSG_NOSIGNAL); + if (!result) { + LOG("Error %d while sending data\n", result); + } + } else { + send_all(pTCP->packet, pTCP->offset + MB_TCP_HEADER_SIZE, MSG_NOSIGNAL); + } + } + else + { + pTCP->packet[1]++; //Increment ID packet + result=send(pTCP->sock, pTCP->packet, pTCP->offset + MB_TCP_HEADER_SIZE, MSG_NOSIGNAL); + if (!result) { + LOG("Error %d while sending data\n", result); + } + } + if (!quiet) + LOG("Send TCP modbus data len=%d, mode=%d, sock=%d\n",pTCP->offset+MB_TCP_HEADER_SIZE, server, pTCP->sock); + }else{ + + } + }else{ + pTCP->state = 0; + } + break; + } + count++; + + } +// result = timerfd_settime(pTCP->timer, 0, &pTCP->newValue, &oldValue); +// if(result < 0){ +// LOG("Error while timer setup \n"); +// } + +} +void SendModbusTCP(struct fdStructType *threadFD,char *pBuf, int len, int quiet){ + int count=0; + int result; + struct itimerspec oldValue; + + if(threadFD == NULL || pBuf == NULL || !len)return; + if(len > MAX_PACK_SIZE) return; + + t_mb_tcp *pTCP= &threadFD->mb_tcp; + + while(count < len){ + InsertByteModbusTCP(pTCP, pBuf[count++]); + result = timerfd_settime(pTCP->timer, 0, &pTCP->newValue, &oldValue); + if(pTCP->offset >= MAX_PACK_SIZE){ + pTCP->offset=0; + bzero(pTCP->packet,MAX_PACK_SIZE); + break; + } + } + if (!quiet) + LOG("Start timeout RTU pack\n"); + //restart package timer + result = timerfd_settime(pTCP->timer, 0, &pTCP->newValue, &oldValue); + if(result < 0) + { + if (!quiet) + LOG("Error while timer setup \n"); + } + ; +} + +void EndTimeoutModbusTCP(struct fdStructType *threadFD, uint8_t server, int ascii_rtu, uint8_t connection_mode, int quiet){ + int result = 0; + uint16_t crc1, crc2; + uint8_t low_byte, high_byte; + if(threadFD == NULL)return; + + t_mb_tcp *pTCP= &threadFD->mb_tcp; + + if(ascii_rtu == 2){ + pTCP->state = 0; + if (!quiet) + LOG("End timeout receive modbus ASCII packet"); + return; + } + if (!quiet) + LOG("End timeout RTU pack\n"); + + if (pTCP->offset<4) { + if (!quiet) + LOG("Invalid RTU pack, skip\n"); + return; + } + + crc1 = crc16((uint8_t *)&pTCP->packet[MB_TCP_HEADER_SIZE], pTCP->offset-2); + high_byte = pTCP->packet[pTCP->offset+MB_TCP_HEADER_SIZE-1]; + low_byte = pTCP->packet[pTCP->offset+MB_TCP_HEADER_SIZE-2]; + crc2 = (uint16_t)high_byte<<8 | (uint16_t)low_byte; + if (!quiet) + LOG("Check CRC pack/ Device CRC= %d, calculating CRC=%d\n",crc2,crc1); + if(crc1 == crc2){ + pTCP->offset -= 2; + memcpy(pTCP->packet,threadFD->state_rtu.header, MB_TCP_HEADER_SIZE); + pTCP->packet[MB_TCP_HEADER_LEN] = (uint8_t)pTCP->offset; + if(server) + { + if(connection_mode == 0) + { + result=send(pTCP->sock, pTCP->packet, pTCP->offset + MB_TCP_HEADER_SIZE, MSG_NOSIGNAL); + if (!result) { + LOG("Error %d while sending data\n", result); + } + } else { + send_all(pTCP->packet, pTCP->offset + MB_TCP_HEADER_SIZE, MSG_NOSIGNAL); + } + } else { + pTCP->packet[1]++; //Increment ID packet + result=send(pTCP->sock, pTCP->packet, pTCP->offset + MB_TCP_HEADER_SIZE, MSG_NOSIGNAL); + if (!result) { + LOG("Error %d while sending data\n", result); + } + } + if (!quiet) + LOG("Send TCP modbus data len=%d, mode=%d, sock=%d\n",pTCP->offset+MB_TCP_HEADER_SIZE, server, pTCP->sock); + } + pTCP->offset = 0; +} + +// Read all config for current device from UCI +// WARNING: indian code detected!!! +device_config_t GetFullDeviceConfig(int deviceID) +{ + LOG("Reading settings of ID %d \n", deviceID); + + char *STRING_DISABLED = "disabled"; + char *STRING_SERVER = "server"; + char *STRING_CLIENT = "client"; + + device_config_t deviceConfig = {0}; + + // maybe use malloc? what about overhead? + char UCIpathBegin[MAX_CHARS_IN_UCIPATH] = "pollmydevice."; + + char UCIpathMode[MAX_CHARS_IN_UCIPATH] = ".mode"; + char UCIpathDeviceName[MAX_CHARS_IN_UCIPATH] = ".devicename"; + char UCIpathBaudRate[MAX_CHARS_IN_UCIPATH] = ".baudrate"; + char UCIpathBytesize[MAX_CHARS_IN_UCIPATH] = ".bytesize"; + char UCIpathParity[MAX_CHARS_IN_UCIPATH] = ".parity"; + char UCIpathFlowControl[MAX_CHARS_IN_UCIPATH] = ".flowcontrol"; + char UCIpathStopBits[MAX_CHARS_IN_UCIPATH] = ".stopbits"; + char UCIpathServerPort[MAX_CHARS_IN_UCIPATH] = ".server_port"; + char UCIpathConnectionMode[MAX_CHARS_IN_UCIPATH] = ".connection_mode"; + char UCIpathHoldConnTime[MAX_CHARS_IN_UCIPATH] = ".holdconntime"; + char UCIpathClientHost[MAX_CHARS_IN_UCIPATH] = ".client_host"; + char UCIpathClientPort[MAX_CHARS_IN_UCIPATH] = ".client_port"; + char UCIpathClientAuth[MAX_CHARS_IN_UCIPATH] = ".client_auth"; + char UCIpathClientTimeout[MAX_CHARS_IN_UCIPATH] = ".client_timeout"; + char UCIpathClientID[MAX_CHARS_IN_UCIPATH] = ".client_id"; + char UCIpathModbusGateway[MAX_CHARS_IN_UCIPATH] = ".modbus_gateway"; + char UCIpathQuiet[MAX_CHARS_IN_UCIPATH] = ".quiet"; + char UCIpathPackTimeout[MAX_CHARS_IN_UCIPATH] = ".pack_timeout"; + char UCIpathPackSize[MAX_CHARS_IN_UCIPATH] = ".pack_size"; + char UCIpathRS485Mode[MAX_CHARS_IN_UCIPATH] = ".rs485_mode"; + // -------------------------------------------- max = 15 symbols, use TMP_PATH_LENGTH + + char UCIpathNumber[MAX_DIGITS_IN_DEV_NUM]; + char UCIpath[MAX_CHARS_IN_UCIPATH]; + snprintf(UCIpathNumber, MAX_DIGITS_IN_DEV_NUM, "%d", deviceID); // ConvertToString(deviceID) + + struct uci_ptr UCIptr; + struct uci_context *UCIcontext = uci_alloc_context(); + if(!UCIcontext) + return deviceConfig; + + // mode + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); // UCIpath = UCIpathBegin = "pollmydevice." + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); // UCIpath + (char)i + strncat(UCIpath, UCIpathMode, TMP_PATH_LENGTH); // UCIpath + ".mode" + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathMode); + return deviceConfig; + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + { + if(strcmp(UCIptr.o->v.string, STRING_DISABLED) == 0) + deviceConfig.mode = MODE_DISABLED; + else if(strcmp(UCIptr.o->v.string, STRING_SERVER) == 0) + deviceConfig.mode = MODE_SERVER; + else if(strcmp(UCIptr.o->v.string, STRING_CLIENT) == 0) + deviceConfig.mode = MODE_CLIENT; + else + deviceConfig.mode = MODE_DISABLED; + } + + // devicename + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathDeviceName, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathDeviceName); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + memcpy(deviceConfig.deviceName, UCIptr.o->v.string, sizeof(deviceConfig.deviceName)); + + // baudrate + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathBaudRate, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathBaudRate); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.baudRate = atoi(UCIptr.o->v.string); + + // bytesize + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathBytesize, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathBytesize); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.byteSize = atoi(UCIptr.o->v.string); + + // parity + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathParity, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathParity); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + { + if(memcmp(UCIptr.o->v.string, "even", 4) == 0) + deviceConfig.parity = PARITY_EVEN; + else if(memcmp(UCIptr.o->v.string, "odd", 3) == 0) + deviceConfig.parity = PARITY_ODD; + else + deviceConfig.parity = PARITY_NONE; + } + + // flow control + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathFlowControl, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathFlowControl); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + { + if(memcmp(UCIptr.o->v.string, "XON/XOFF", 3) == 0) + deviceConfig.flowcontrol = FC_XONXOFF; + else if(memcmp(UCIptr.o->v.string, "RTS/CTS", 3) == 0) + deviceConfig.flowcontrol = FC_RTSCTS; + else + deviceConfig.flowcontrol = FC_NONE; + } + + // stopbits + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathStopBits, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathStopBits); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.stopBits = atoi(UCIptr.o->v.string); + + // server_port + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathServerPort, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathServerPort); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.serverPort = atoi(UCIptr.o->v.string); + + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathConnectionMode, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathConnectionMode); + deviceConfig.connection_mode = 0; + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.connection_mode = atoi(UCIptr.o->v.string); + + // holdconntime + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathHoldConnTime, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathHoldConnTime); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.holdConnTime = atoi(UCIptr.o->v.string); + if(deviceConfig.holdConnTime==0){ + LOG("Connection hold time not set. Set value to 60 sec\n"); + deviceConfig.holdConnTime = 60; + } + // client_host + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathClientHost, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathClientHost); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + memcpy(deviceConfig.clientHost, UCIptr.o->v.string, sizeof(deviceConfig.clientHost)); + + // client_port + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathClientPort, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathClientPort); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.clientPort = atoi(UCIptr.o->v.string); + + // client_auth + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathClientAuth, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathClientAuth); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.clientAuth = atoi(UCIptr.o->v.string); + + // client_timeout + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathClientTimeout, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathClientTimeout); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.clientTimeout = atoi(UCIptr.o->v.string); + + FILE * pFuseFile; + char * serialNum = malloc(IMEI_LENGTH); + + char serialNumPath[256]; + snprintf(serialNumPath, sizeof(serialNumPath), "/tmp/pollmydevice/client_id%d", deviceID); + pFuseFile = fopen(serialNumPath, "r"); + if (pFuseFile == NULL) + { + deviceConfig.clientID = 0; + LOG("S/N for dev %d not found in the %s\n", deviceID, serialNumPath); + } + else + { + if (fgets(serialNum, IMEI_LENGTH+1, pFuseFile) == NULL) + { + deviceConfig.clientID = 0; + LOG("S/N for dev %d is incorrect\n", deviceID); + } + else + { + deviceConfig.clientID = strtoll(serialNum, NULL, 10); + LOG("S/N dev %d = %lld\n", deviceID, deviceConfig.clientID); + } + fclose(pFuseFile); + } + if (serialNum) + free(serialNum); + + //Modbus Gateway + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathModbusGateway, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathModbusGateway); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.modbus_gateway = atoi(UCIptr.o->v.string); + + // quiet mode + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathQuiet, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathQuiet); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.quiet = atoi(UCIptr.o->v.string); + + // pack_timeout + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathPackTimeout, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathPackTimeout); + deviceConfig.timeout_pack=0; + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.timeout_pack = atoi(UCIptr.o->v.string); + + // pack_size + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathPackSize, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathPackSize); + deviceConfig.size_pack=0; + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) + deviceConfig.size_pack = atoi(UCIptr.o->v.string); + + // rs485_mode + memcpy(UCIpath , UCIpathBegin, MAX_CHARS_IN_UCIPATH); + strncat(UCIpath, UCIpathNumber, MAX_DIGITS_IN_DEV_NUM-2); + strncat(UCIpath, UCIpathRS485Mode, TMP_PATH_LENGTH); + if ((uci_lookup_ptr(UCIcontext, &UCIptr, UCIpath, true) != UCI_OK)|| + (UCIptr.o==NULL || UCIptr.o->v.string==NULL)) + { + LOG("No UCI field %s \n", UCIpathRS485Mode); + } + if(UCIptr.flags & UCI_LOOKUP_COMPLETE) { + deviceConfig.rs485_mode = atoi(UCIptr.o->v.string); + } + + uci_free_context(UCIcontext); + return deviceConfig; +} + +// from Evgeniy Korovin +int FormAuthAnswer(char *dataBuffer, long long int clientID) +{ + int i, len_out; + uint16_t crc; + + memset(dataBuffer,0, 80); + + char stringClientID[15]; + sprintf(stringClientID, "%lld", clientID); // to string + + dataBuffer[0] = 0xC0; + dataBuffer[1] = 0x00; + dataBuffer[2] = 0x07; + dataBuffer[3] = 0x00; + dataBuffer[4] = 0x3F; + dataBuffer[5] = 0x01; // auth counter + + memcpy(&dataBuffer[6], &stringClientID[0], 15); // copy imei to buffer + + dataBuffer[67] = 0x01; //Аворизация по основному каналу + + crc = Crc16Block((uint8_t *)&dataBuffer[1], 67); + len_out = 68; + + for(i = 0; i < 2; i++) + { + uint8_t temp = (uint8_t)(crc>>(i*8)); + if(temp == 0xC0 || temp == 0xC2 || temp == 0xC4) + { + dataBuffer[len_out++] = 0xC4; + if(temp != 0xC4) + dataBuffer[len_out++] = temp+1; + else + dataBuffer[len_out++] = 0xC4; + } + else + dataBuffer[len_out++] = temp; + } + dataBuffer[len_out++] = 0xC2; + + return len_out; +} + +static const uint16_t Crc16Table[256] = { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, + 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, + 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485, + 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4, + 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, + 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, + 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, + 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, + 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, + 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, + 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70, + 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78, + 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F, + 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, + 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, + 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C, + 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3, + 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A, + 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, + 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, + 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, + 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, + 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0 +}; + +uint16_t Crc16Block(uint8_t* block, uint16_t len) +{ + uint16_t crc = 0xFFFF; + while (len--) + { + crc = (crc << 8) ^ Crc16Table[(crc >> 8) ^ *block++]; + } + return crc; +} + +void send_all(const void *dataBuffer, size_t numOfReadBytes, int flags){ + int descr=-1, result=0; + start_request_descr(); + while(get_next_descr(&descr)==0) { + result = send(descr, dataBuffer, numOfReadBytes, flags); + if (!result) { + LOG("Error %d while sending data\n", result); + } + } +} diff --git a/powersupply/Makefile b/powersupply/Makefile new file mode 100755 index 00000000..05d2b106 --- /dev/null +++ b/powersupply/Makefile @@ -0,0 +1,40 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=powersupply +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/powersupply + +include $(INCLUDE_DIR)/package.mk + +define Package/powersupply + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Power Supply for LT70 + PKGARCH:=all +endef + +define Package/powersupply/description + This package contains a utility for powersupply +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/powersupply/install + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/powersupply.config $(1)/etc/config/powersupply + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/powersupply.init $(1)/etc/init.d/powersupply + $(INSTALL_DIR) $(1)/usr/libexec/rpcd + $(INSTALL_BIN) ./files/powersupply.rpcd $(1)/usr/libexec/rpcd/powersupply +endef + +$(eval $(call BuildPackage,powersupply)) diff --git a/powersupply/files/powersupply.config b/powersupply/files/powersupply.config new file mode 100644 index 00000000..07e9624a --- /dev/null +++ b/powersupply/files/powersupply.config @@ -0,0 +1,10 @@ +config system 'system' + option poe_out_power_gpio '627' + option poe_out_power '0' + option poe_out_control '1' + option usb_power_gpio '629' + option usb_power '1' + option usb_control '1' + option ext_power_gpio '626' + option ext_power '0' + diff --git a/powersupply/files/powersupply.init b/powersupply/files/powersupply.init new file mode 100755 index 00000000..7786778e --- /dev/null +++ b/powersupply/files/powersupply.init @@ -0,0 +1,62 @@ +#!/bin/sh /etc/rc.common + +START=11 +STOP=10 +USE_PROCD=1 + +start_service() { + poe_out_power_enabled="$(uci -q get powersupply.system.poe_out_power)" + poe_out_power_gpio="$(uci -q get powersupply.system.poe_out_power_gpio)" + voltage_threshold="$(cat /sys/class/i2c-dev/i2c-0/device/0-0011/voltage_threshold)" + input_voltage="$(cat /sys/class/i2c-dev/i2c-0/device/0-0011/input_voltage)" + if [[ "$input_voltage" -lt "$voltage_threshold" ]]; then + echo 0 > /sys/class/gpio/gpio$poe_out_power_gpio/value + else + echo $poe_out_power_enabled > /sys/class/gpio/gpio$poe_out_power_gpio/value + fi + poe_out_power_control="$(uci -q get powersupply.system.poe_out_control)" + echo $poe_out_power_control > /sys/class/i2c-dev/i2c-0/device/0-0011/poeout_control + + ext_power_enabled="$(uci -q get powersupply.system.ext_power)" + ext_power_gpio="$(uci -q get powersupply.system.ext_power_gpio)" + echo $ext_power_enabled > /sys/class/gpio/gpio$ext_power_gpio/value + + usb_power_enabled="$(uci -q get powersupply.system.usb_power)" + usb_power_gpio="$(uci -q get powersupply.system.usb_power_gpio)" + echo $usb_power_enabled > /sys/class/gpio/gpio$usb_power_gpio/value + usb_power_control="$(uci -q get powersupply.system.usb_control)" + echo $usb_power_control > /sys/class/i2c-dev/i2c-0/device/0-0011/usb_control +} + +stop_service() { + poe_out_power_gpio="$(uci -q get powersupply.system.poe_out_power_gpio)" + echo 0 > /sys/class/gpio/gpio$poe_out_power_gpio/value + + ext_power_gpio="$(uci -q get powersupply.system.ext_power_gpio)" + echo 0 > /sys/class/gpio/gpio$ext_power_gpio/value + + usb_power_gpio="$(uci -q get powersupply.system.usb_power_gpio)" + echo 0 > /sys/class/gpio/gpio$usb_power_gpio/value +} + +boot() { + poe_gpio="$(uci -q get powersupply.system.poe_out_power_gpio)" + echo $poe_gpio > /sys/class/gpio/export + usb_gpio="$(uci -q get powersupply.system.usb_power_gpio)" + echo $usb_gpio > /sys/class/gpio/export + ext_gpio="$(uci -q get powersupply.system.ext_power_gpio)" + echo $ext_gpio > /sys/class/gpio/export + start +} + +shutdown() { + stop_service +} + +service_triggers() { + procd_add_reload_trigger "powersupply" +} + +reload_service() { + restart +} diff --git a/powersupply/files/powersupply.rpcd b/powersupply/files/powersupply.rpcd new file mode 100755 index 00000000..2c021bd8 --- /dev/null +++ b/powersupply/files/powersupply.rpcd @@ -0,0 +1,34 @@ +#!/bin/sh + +case "$1" in + list) + echo '{ "info": { } }' + ;; + call) + case "$2" in + info) + input_voltage=$(cat /sys/class/i2c-dev/i2c-0/device/0-0011/input_voltage) + voltage_threshold=$(cat /sys/class/i2c-dev/i2c-0/device/0-0011/voltage_threshold) + poe_out_control=$(cat /sys/class/i2c-dev/i2c-0/device/0-0011/poeout_control) + usb_power_control=$(cat /sys/class/i2c-dev/i2c-0/device/0-0011/usb_control) + + poe_out_power_gpio=$(uci -q get powersupply.system.poe_out_power_gpio) + poe_out_power=$(cat /sys/class/gpio/gpio$poe_out_power_gpio/value) + ext_power_gpio="$(uci -q get powersupply.system.ext_power_gpio)" + ext_power=$(cat /sys/class/gpio/gpio$ext_power_gpio/value) + usb_power_gpio="$(uci -q get powersupply.system.usb_power_gpio)" + usb_power=$(cat /sys/class/gpio/gpio$usb_power_gpio/value) + + echo '{' + echo "\"input_voltage\": \"$input_voltage\", " + echo "\"voltage_threshold\": \"$voltage_threshold\", " + echo "\"poe_out_power\": \"$poe_out_power\", " + echo "\"poe_out_control\": \"$poe_out_control\", " + echo "\"usb_power\": \"$usb_power\", " + echo "\"usb_power_control\": \"$usb_power_control\", " + echo "\"7v5_power\": \"$ext_power\"" + echo '}' + ;; + esac + ;; +esac \ No newline at end of file diff --git a/pptpd-ext/Makefile b/pptpd-ext/Makefile new file mode 100755 index 00000000..883b33be --- /dev/null +++ b/pptpd-ext/Makefile @@ -0,0 +1,50 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=pptpd-ext +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/pptpd-ext + +include $(INCLUDE_DIR)/package.mk + +define Package/pptpd-ext + TITLE:=pptpd server additional scripts + SECTION:=net + CATEGORY:=Network + SUBMENU:=VPN + PKGARCH:=all +endef + +define Package/pptpd-ext/description + This package contains additional scripts and configuration files for pptpd +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/pptpd-ext/install + $(INSTALL_DIR) $(1)/etc + $(CP) ./files/pptpd.conf $(1)/etc/pptpd.conf + + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/pptpd.init $(1)/etc/init.d/pptpd + + $(INSTALL_DIR) $(1)/usr/lib/pptpd + $(INSTALL_BIN) ./files/pptp-up $(1)/usr/lib/pptpd/pptp-up + $(INSTALL_BIN) ./files/pptp-down $(1)/usr/lib/pptpd/pptp-down + + $(INSTALL_DIR) $(1)/etc/ppp + $(CP) ./files/options.pptpd $(1)/etc/ppp/options.pptpd + + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/pptpd.config $(1)/etc/config/pptpd +endef + +$(eval $(call BuildPackage,pptpd-ext)) diff --git a/pptpd-ext/files/options.pptpd b/pptpd-ext/files/options.pptpd new file mode 100644 index 00000000..ed65c40b --- /dev/null +++ b/pptpd-ext/files/options.pptpd @@ -0,0 +1,25 @@ +#debug +#logfile /tmp/pptp-server.log +auth +name "pptp-server" +lcp-echo-failure 3 +lcp-echo-interval 20 +default-asyncmap +mtu 1482 +mru 1482 +nobsdcomp +nodeflate +#noproxyarp +#nomppc +require-mschap-v2 +refuse-chap +refuse-mschap +refuse-eap +refuse-pap +#ms-dns 172.16.1.1 +#plugin radius.so +#radius-config-file /etc/radius.conf +ip-up-script /usr/lib/pptpd/pptp-up +#ipv6-up-script /usr/lib/pptpd/pptp-up +ip-down-script /usr/lib/pptpd/pptp-down +#ipv6-down-script /usr/lib/pptpd/pptp-down diff --git a/pptpd-ext/files/pptp-down b/pptpd-ext/files/pptp-down new file mode 100644 index 00000000..12ed3abb --- /dev/null +++ b/pptpd-ext/files/pptp-down @@ -0,0 +1,10 @@ +#!/bin/sh + +sed -i "/$1/d" /tmp/pptpd/clients + +[ -d /etc/ppp/ip-down.d ] && { + for SCRIPT in /etc/ppp/ip-down.d/* + do + [ -x "$SCRIPT" ] && "$SCRIPT" "$@" + done +} diff --git a/pptpd-ext/files/pptp-up b/pptpd-ext/files/pptp-up new file mode 100644 index 00000000..54f50a9a --- /dev/null +++ b/pptpd-ext/files/pptp-up @@ -0,0 +1,17 @@ +#!/bin/sh + +mkdir /tmp/pptpd +echo "ifname:$1;server:$4;client:$5;ip:$6" >> /tmp/pptpd/clients + +section=$(uci show pptpd | grep $5 | awk -F '.' '{print $2}') +route=$(uci get pptpd.$section.route) +[ -n "$route" ] && { + ip route add $route via $4 dev $1 +} + +[ -d /etc/ppp/ip-up.d ] && { + for SCRIPT in /etc/ppp/ip-up.d/* + do + [ -x "$SCRIPT" ] && "$SCRIPT" "$@" + done +} diff --git a/pptpd-ext/files/pptpd.conf b/pptpd-ext/files/pptpd.conf new file mode 100644 index 00000000..398ae9d3 --- /dev/null +++ b/pptpd-ext/files/pptpd.conf @@ -0,0 +1,4 @@ +#debug +speed 115200 +stimeout 10 +#localip & remoteip are not needed, ip management is done by pppd diff --git a/pptpd-ext/files/pptpd.config b/pptpd-ext/files/pptpd.config new file mode 100644 index 00000000..6ece80ae --- /dev/null +++ b/pptpd-ext/files/pptpd.config @@ -0,0 +1,4 @@ +config service 'pptpd' + option 'enabled' '0' + option 'logwtmp' '1' + diff --git a/pptpd-ext/files/pptpd.init b/pptpd-ext/files/pptpd.init new file mode 100644 index 00000000..6874493e --- /dev/null +++ b/pptpd-ext/files/pptpd.init @@ -0,0 +1,96 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2015 OpenWrt.org + +START=60 +USE_PROCD=1 + +BIN=/usr/sbin/pptpd +CONFIG=/var/etc/pptpd.conf +CHAP_SECRETS=/var/etc/chap-secrets +OPTIONS_PPTP=/var/etc/options.pptpd + +validate_login_section() { + uci_load_validate pptpd login "$1" "$2" \ + 'enabled:uinteger' \ + 'username:string' \ + 'password:string' \ + 'remoteip:string' +} + +validate_pptpd_section() { + uci_load_validate pptpd service "$1" "$2" \ + 'enabled:uinteger' \ + 'localip:string' \ + 'remoteip_start:string' \ + 'remoteip_end:string' \ + 'mppe:list(string):required no40 no56 stateless' \ + 'logwtmp:uinteger' +} + +setup_login() { + [ "$2" = 0 ] || { + echo "validation failed" + return 1 + } + + [ "$enabled" -eq 1 ] || return 0 + [ -n "$username" ] || return 0 + [ -n "$password" ] || return 0 + [ -n "$remoteip" ] || remoteip=* + + echo "$username pptp-server $password $remoteip" >> $CHAP_SECRETS +} + +setup_config() { + [ "$2" = 0 ] || { + echo "validation failed" + return 1 + } + + [ "$enabled" -eq 0 ] && return 1 + + mkdir -p /var/etc + cp /etc/pptpd.conf $CONFIG + cp /etc/ppp/options.pptpd $OPTIONS_PPTP + + [ -n "$localip" ] && echo "localip $localip" >> $CONFIG + [ -n "$remoteip_start" ] && [ -n "$remoteip_end" ] && echo "remoteip $remoteip_start-${remoteip_end##*.}" >> $CONFIG + [ "$logwtmp" -eq 1 ] && echo "logwtmp" >> $CONFIG + + echo "mppe $(echo $mppe | sed -e 's/\s/,/g')" >> $OPTIONS_PPTP + + return 0 +} + +start_service() { + config_load pptpd + validate_pptpd_section pptpd setup_config || return + sed -i '/pptp-server/d' $CHAP_SECRETS + config_foreach validate_login_section login setup_login + + ln -sfn $CHAP_SECRETS /etc/ppp/chap-secrets + + procd_open_instance + procd_set_param command $BIN -c $CONFIG --fg -o $OPTIONS_PPTP + procd_set_param respawn + procd_close_instance +} + +service_triggers() { + procd_add_reload_trigger "pptpd" + + procd_open_validate + validate_pptpd_section + validate_login_section + procd_close_validate +} + +stop_service() { + ps | grep "$OPTIONS_PPTP" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 + rm /tmp/pptpd/clients >/dev/null 2>&1 +} + +reload_service() { + stop + start +} diff --git a/report/Makefile b/report/Makefile new file mode 100755 index 00000000..f3a8b19d --- /dev/null +++ b/report/Makefile @@ -0,0 +1,38 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=report +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/report + +include $(INCLUDE_DIR)/package.mk + +define Package/report + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Generate report + DEPENDS:= +endef + +define Package/report/description + Utility to generate report +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/report/install + $(INSTALL_DIR) $(1)/bin + $(INSTALL_BIN) ./files/report $(1)/bin/ + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/report.config $(1)/etc/config/report +endef + +$(eval $(call BuildPackage,report)) diff --git a/report/files/report b/report/files/report new file mode 100755 index 00000000..7fc2455f --- /dev/null +++ b/report/files/report @@ -0,0 +1,65 @@ +#!/bin/sh + +mkdir /tmp/report + +cp /etc/openwrt_release /tmp/report/openwrt_release.txt + +if [[ "$(uci -q get report.@report[0].kernel)" -eq "1" ]]; then + dmesg &> /tmp/report/dmesg.txt +fi + +if [[ "$(uci -q get report.@report[0].system)" -eq "1" ]]; then + logread &> /tmp/report/logread.txt + log_file=$(uci -q get system.@system[0].log_file) + if [[ -n "$log_file" ]]; then + cp ${log_file} /tmp/report/logfile.txt + cp ${log_file}.old /tmp/report/logfile.old.txt + fi +fi + +if [[ "$(uci -q get report.@report[0].network)" -eq "1" ]]; then + cp /etc/config/network /tmp/report/network.txt + cp /etc/config/firewall /tmp/report/firewall.txt + cp /etc/config/wireless /tmp/report/wireless.txt + route -n &> /tmp/report/route.txt + ifconfig &> /tmp/report/ifconfig.txt + iptables -S &> /tmp/report/iptables.txt +fi + +if [[ "$(uci -q get report.@report[0].simman)" -eq "1" ]]; then + cp /etc/config/simman2 /tmp/report/simman2.txt + simman2_cli -a core &> /tmp/report/simman2_cli.txt +fi + +if [[ "$(uci -q get report.@report[0].openvpn)" -eq "1" ]]; then + cp /etc/config/openvpn /tmp/report/openvpn.txt +fi + +if [[ "$(uci -q get report.@report[0].mwan)" -eq "1" ]]; then + cp /etc/config/mwan3 /tmp/report/mwan.txt +fi + +if [[ "$(uci -q get report.@report[0].pollmydevice)" -eq "1" ]]; then + cp /etc/config/pollmydevice /tmp/report/pollmydevice.txt +fi + +if [[ "$(uci -q get report.@report[0].ntp)" -eq "1" ]]; then + ntpq -p &> /tmp/report/ntpqp.txt + cp /etc/ntp.conf /tmp/report/ntp.txt +fi + +if [[ "$(uci -q get report.@report[0].smsd)" -eq "1" ]]; then + cp /etc/config/smscontrol /tmp/report/smscontrol.txt + cp /etc/smsd.conf /tmp/report/smsd.txt + cp /var/log/smsd.log /tmp/report/smsdlog.txt +fi + +if [[ "$(uci -q get report.@report[0].snmp)" -eq "1" ]]; then + cp /etc/config/snmpd /tmp/report/snmpd.txt +fi + +cd /tmp/ && tar -czf /tmp/report.tar.gz report 2>/dev/null + +rm -rf /tmp/report/ + +exit 0 \ No newline at end of file diff --git a/report/files/report.config b/report/files/report.config new file mode 100644 index 00000000..d4f68c97 --- /dev/null +++ b/report/files/report.config @@ -0,0 +1,11 @@ +config report + option kernel '1' + option system '1' + option network '1' + option openvpn '1' + option ntp '1' + option snmp '1' + option simman '1' + option mwan '1' + option pollmydevice '1' + option smsd '1' diff --git a/simman/Makefile b/simman/Makefile new file mode 100755 index 00000000..a5839090 --- /dev/null +++ b/simman/Makefile @@ -0,0 +1,65 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=simman +PKG_VERSION:=3 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/simman +#CMAKE_INSTALL:=1 + +PKG_MAINTAINER:=Konstantin Sklyarec Vladimir Ovseychuk + +include $(INCLUDE_DIR)/package.mk +#include $(INCLUDE_DIR)/cmake.mk + +define Package/simman + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Manager for SIM card in 3g modem + DEPENDS:=+libuci +endef + +TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include +TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib + +define Package/simman/description + This package contains utility for sim check manage. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Package/simman/install + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/simman $(1)/sbin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/simman_getinfo $(1)/sbin/ + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/simman.config $(1)/etc/config/simman + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/simman.init $(1)/etc/init.d/simman + $(INSTALL_DIR) $(1)/etc/simman + $(INSTALL_BIN) ./files/nbinfo.sh $(1)/etc/simman/nbinfo.sh + $(INSTALL_BIN) ./files/setsim.sh $(1)/etc/simman/setsim.sh + $(INSTALL_BIN) ./files/getccid.sh $(1)/etc/simman/getccid.sh + $(INSTALL_BIN) ./files/getimei.sh $(1)/etc/simman/getimei.sh + $(INSTALL_BIN) ./files/setfun.sh $(1)/etc/simman/setfun.sh + $(INSTALL_BIN) ./files/getreg.sh $(1)/etc/simman/getreg.sh + $(INSTALL_BIN) ./files/getgprsreg.sh $(1)/etc/simman/getgprsreg.sh + $(INSTALL_BIN) ./files/getsiglev.sh $(1)/etc/simman/getsiglev.sh + $(INSTALL_BIN) ./files/getpinstat.sh $(1)/etc/simman/getpinstat.sh + $(INSTALL_BIN) ./files/getbasestid.sh $(1)/etc/simman/getbasestid.sh + $(INSTALL_BIN) ./files/getnettype.sh $(1)/etc/simman/getnettype.sh + $(INSTALL_BIN) ./files/getband.sh $(1)/etc/simman/getband.sh + $(INSTALL_BIN) ./files/getsimcheck.sh $(1)/etc/simman/getsimcheck.sh + $(INSTALL_BIN) ./files/getpackinfo.sh $(1)/etc/simman/getpackinfo.sh + $(INSTALL_BIN) ./files/getcsq.sh $(1)/etc/simman/getcsq.sh + $(INSTALL_BIN) ./files/check_prio.sh $(1)/etc/simman/check_prio.sh + $(CP) ./files/*.gcom $(1)/etc/simman + $(INSTALL_DIR) $(1)/etc/hotplug.d/usb + $(INSTALL_DATA) ./files/simman.hotplug $(1)/etc/hotplug.d/usb/12-modem + $(INSTALL_DATA) ./files/scmux.hotplug $(1)/etc/hotplug.d/usb/13-scmux +endef + +$(eval $(call BuildPackage,simman)) diff --git a/simman/README.md b/simman/README.md new file mode 100755 index 00000000..8aa081aa --- /dev/null +++ b/simman/README.md @@ -0,0 +1,8 @@ + +# Модуль управления СИМ картами 3g модема + +## Описание +Модуль предназначен для управления переключением СИМ карт 3G модема. + +Настроечный файл лежит по пути /etc/config/simman. +Установку параметров можно произвести из консоли, путем редактирования параметров в файле настроек или через веб во вкладке Services/Simman. diff --git a/simman/files/check_prio.sh b/simman/files/check_prio.sh new file mode 100755 index 00000000..c96adca2 --- /dev/null +++ b/simman/files/check_prio.sh @@ -0,0 +1,176 @@ +#!/bin/sh + +EPMTY_SIM=$(/etc/simman/getsimcheck.sh | grep "NOT INSERTED") +if [[ -n "$EPMTY_SIM" ]]; then + echo "One or both SIM cards are not inserted" + exit 1 +fi + +/etc/init.d/simman stop &>/dev/null + +TESTIP0=$(uci -q get simman.core.testip && uci -q get simman.@sim0[0].testip) +TESTIP1=$(uci -q get simman.core.testip && uci -q get simman.@sim1[0].testip) +ATPORT=$(uci -q get simman.core.atdevice) +IFNAME=$(uci -q get simman.core.iface) + +LOG_PATH=$3 +if [[ -z "$LOG_PATH" ]]; then + LOG_PATH=/tmp/sim_prio_log +fi + +PING0=0 +PING1=0 + +ASU=0 +ASU0=0 +ASU1=0 +NET0=2 +NET1=2 + +ASU2G=$(echo $1 | grep "2G" | awk -F':' '{print $2}') +if [[ -z "$ASU2G" ]]; then + ASU2G=0 +fi +ASU3G=$(echo $2 | grep "3G" | awk -F':' '{print $2}') +if [[ -z "$ASU3G" ]]; then + ASU3G=0 +fi + +#echo $ASU2G:$ASU3G + +UP_COUNT=0 +DOWN_COUNT=0 + +set_high(){ + if [[ "$1" -eq "0" ]]; then + uci set simman.@sim0[0].priority='1' + uci set simman.@sim1[0].priority='0' + echo "$(date): set high SIM0" >> $LOG_PATH + elif [[ "$1" -eq "1" ]]; then + uci set simman.@sim0[0].priority='0' + uci set simman.@sim1[0].priority='1' + echo "$(date): set high SIM1" >> $LOG_PATH + fi +} + +/etc/simman/setsim.sh -s0 +sleep 60 + +for IP in $TESTIP0 +do + COUNT=0 + while [[ "$COUNT" -le "2" ]]; do + ping -w5 -c1 -s8 -I $IFNAME $IP &> /dev/null + if [[ "$?" -eq "0" ]]; then + let UP_COUNT++ + PING0=1 + else + let DOWN_COUNT++ + fi + ASU=$(gcom -d $ATPORT -s /etc/simman/getsiglev.gcom | awk -F',' '{print $1}') + if [[ "$ASU" -eq "99" ]]; then + ASU=0 + fi + if [[ "$ASU" -gt "$ASU0" ]]; then + ASU0=$ASU + fi + #echo $ASU0 + sleep 2 + let COUNT++ + done +done + +#echo "UP:$UP_COUNT;DOWN:$DOWN_COUNT" +#echo ASU0$ASU0 + +NET=$(/etc/simman/getnettype.sh) +if [[ "$NET" == "3G" ]]; then + NET0=3 +fi +#echo NET:$NET + +UP_COUNT=0 +DOWN_COUNT=0 +ASU=0 +NET=0 + +/etc/simman/setsim.sh -s1 +sleep 60 + +for IP in $TESTIP1 +do + COUNT=0 + while [[ "$COUNT" -le "2" ]]; do + ping -w5 -c1 -s8 -I $IFNAME $IP &> /dev/null + if [[ "$?" -eq "0" ]]; then + let UP_COUNT++ + PING1=1 + else + let DOWN_COUNT++ + fi + ASU=$(gcom -d $ATPORT -s /etc/simman/getsiglev.gcom | awk -F',' '{print $1}') + if [[ "$ASU" -eq "99" ]]; then + ASU=0 + fi + if [[ "$ASU" -gt "$ASU1" ]]; then + ASU1=$ASU + fi + #echo $ASU1 + sleep 2 + let COUNT++ + done +done + +#echo "UP:$UP_COUNT;DOWN:$DOWN_COUNT" +#echo ASU1$ASU1 + +NET=$(/etc/simman/getnettype.sh) +if [[ "$NET" == "3G" ]]; then + NET1=3 +fi +#echo NET:$NET + +echo "$(date): SIM0: ping=$PING0 NET:$NET0 $ASU0 ASU; SIM1: ping=$PING1 NET:$NET1 $ASU1 ASU" >> $LOG_PATH + +if [[ "$PING0" -eq "0" ]]; then + if [[ "$PING1" -eq "0" ]]; then + echo "Ping is not available on both SIM cards" + if [[ "$NET0" -gt "$NET1" ]]; then + set_high 0 + elif [[ "$NET0" -lt "$NET1" ]]; then + set_high 1 + elif [[ "$ASU0" -gt "$ASU1" ]]; then + set_high 0 + elif [[ "$ASU0" -lt "$ASU1" ]]; then + set_high 1 + fi + else + set_high 1 + fi +else + if [[ "$PING1" -eq "0" ]]; then + set_high 0 + else + if [[ "$NET0" -gt "$NET1" ]]; then + if [[ "$ASU0" -ge "$ASU3G" ]]; then + set_high 0 + elif [[ "$ASU1" -ge "$ASU2G" ]]; then + set_high 1 + fi + elif [[ "$NET0" -lt "$NET1" ]]; then + if [[ "$ASU1" -ge "$ASU3G" ]]; then + set_high 1 + elif [[ "$ASU0" -ge "$ASU2G" ]]; then + set_high 0 + fi + elif [[ "$ASU0" -gt "$ASU1" ]]; then + set_high 0 + elif [[ "$ASU0" -lt "$ASU1" ]]; then + set_high 1 + fi + fi +fi + +/etc/init.d/simman start &>/dev/null + +exit 0 diff --git a/simman/files/getband.sh b/simman/files/getband.sh new file mode 100755 index 00000000..97a22e6f --- /dev/null +++ b/simman/files/getband.sh @@ -0,0 +1,109 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_BASESTINFO="/etc/simman/getbasestinfo.gcom" +SCRIPT_BASESTINFO1="/etc/simman/getenginfo.gcom" +SCRIPT_BASEIDINFO="/etc/simman/getbaseidinfo.gcom" +device="" +BASESTINFO="" +NETTYPE="" +BAND="" +proto="" +counter=0 + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getband.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getband.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + +proto=$(uci -q get simman.core.proto) +if [ "$proto" = "0" ]; then + BASESTINFO=$(gcom -d $device -s $SCRIPT_BASESTINFO) + [ -z "$BASESTINFO" ] && BASESTINFO="NONE" + + NETTYPE=${BASESTINFO:0:2} + + if [ "$NETTYPE" == "3G" ] + then + BAND=$( echo $BASESTINFO | awk -F',' '{print $2}') + [ -z "$BAND" ] && BAND="Search..." + echo "'UARFCN $BAND'" + else + if [ "$NETTYPE" == "2G" ] + then + BAND=$( echo $BASESTINFO | awk -F',' '{print $2}') + [ -z "$BAND" ] && BAND="Search..." + echo "'ARFCN $BAND'" + else + echo "Identification failed" + fi + fi +elif [ "$proto" == 3 ]; then + BASESTINFO=$(gcom -d $device -s $SCRIPT_BASESTINFO1) + [ -z "$BASESTINFO" ] && BASESTINFO="NONE" + + NETTYPE=$( echo $BASESTINFO | awk -F':' '{print $1}') + + if [ "$NETTYPE" == "UMTS" ]; then + BAND=$( echo $BASESTINFO | awk -F'"' '{print $2}' | awk -F',' '{print $1}') + [ -z "$BAND" ] && BAND="Search..." + echo "'UARFCN $BAND'" + elif [ "$NETTYPE" == "GSM" ]; then + BAND=$( echo $BASESTINFO | awk -F'"' '{print $2}' | awk -F',' '{print $1}') + [ -z "$BAND" ] && BAND="Search..." + echo "'ARFCN $BAND'" + fi + +else + BASESTINFO=$(gcom -d $device -s $SCRIPT_BASEIDINFO) + + [ -z "$BASESTINFO" ] && BASESTINFO="NONE" + NETTYPE=$( echo $BASESTINFO | awk -F',' '{print $1}') + + if [ "$NETTYPE" == "LTE" ]; then + BAND=$( echo $BASESTINFO | awk -F',' '{print $8}') + [ -z "$BAND" ] && BAND="Search..." + echo "'EARFCN $BAND'" + else + if [ "$NETTYPE" == "WCDMA" ]; then + BAND=$( echo $BASESTINFO | awk -F',' '{print $8}') + [ -z "$BAND" ] && BAND="Search..." + echo "'UARFCN $BAND'" + else + if [ "$NETTYPE" == "GSM" ]; then + BAND=$( echo $BASESTINFO | awk -F',' '{print $6}') + [ -z "$BAND" ] && BAND="Search..." + echo "'ARFCN $BAND'" + fi + fi + fi +fi + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi + + diff --git a/simman/files/getbaseidinfo.gcom b/simman/files/getbaseidinfo.gcom new file mode 100755 index 00000000..731f2775 --- /dev/null +++ b/simman/files/getbaseidinfo.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CPSI?^m" + waitfor 1 "CPSI: " + get 1 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getbasestid.sh b/simman/files/getbasestid.sh new file mode 100755 index 00000000..c7e3a323 --- /dev/null +++ b/simman/files/getbasestid.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_BASESTINFO="/etc/simman/getbasestinfo.gcom" +SCRIPT_BASESTINFO1="/etc/simman/getbasestinfo1.gcom" +SCRIPT_BASEIDINFO="/etc/simman/getbaseidinfo.gcom" +device="" +BASESTINFO="" +NETTYPE="" +BASESTID="" +proto="" + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getbasestid.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getbasestid.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + +proto=$(uci -q get simman.core.proto) + +if [ "$proto" = "0" ]; then + BASESTINFO=$(gcom -d $device -s $SCRIPT_BASESTINFO) + [ -z "$BASESTINFO" ] && BASESTINFO="NONE" + + NETTYPE=${BASESTINFO:0:2} + + if [ "$NETTYPE" == "3G" ] + then + BASESTID=$( echo $BASESTINFO | awk -F',' '{print $9}') + [ -z "$BASESTID" ] && BASESTID="SEARCH" + echo $BASESTID + else + if [ "$NETTYPE" == "2G" ] + then + BASESTID=$( echo $BASESTINFO | awk -F',' '{print $7}') + [ -z "$BASESTID" ] && BASESTID="SEARCH" + echo $BASESTID + else + echo "Identification failed" + fi + fi +elif [ "$proto" = "3" ]; then + BASESTINFO=$(gcom -d $device -s $SCRIPT_BASESTINFO1) + BASESTID=$( echo $BASESTINFO | awk -F',' '{print $4}') + echo $BASESTID +else + BASESTINFO=$(gcom -d $device -s $SCRIPT_BASEIDINFO) + [ -z "$BASESTINFO" ] && BASESTINFO="NONE" + + BASESTID=$( echo $BASESTINFO | awk -F',' '{print $5}') + BASESTID=$(echo "obase=16; $BASESTID" | bc) + [ -z "$BASESTID" ] && BASESTID="SEARCH" + echo $BASESTID +fi + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi + +exit 0 \ No newline at end of file diff --git a/simman/files/getbasestinfo.gcom b/simman/files/getbasestinfo.gcom new file mode 100755 index 00000000..fb4654bc --- /dev/null +++ b/simman/files/getbasestinfo.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT\^SMONI^m" + waitfor 1 "SMONI: " + get 1 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getbasestinfo1.gcom b/simman/files/getbasestinfo1.gcom new file mode 100755 index 00000000..1760ad3e --- /dev/null +++ b/simman/files/getbasestinfo1.gcom @@ -0,0 +1,17 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CREG=2^m" + waitfor 1 "OK" + send "AT+CREG?^m" + waitfor 1 "+CREG: " + get 1 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getccid.gcom b/simman/files/getccid.gcom new file mode 100755 index 00000000..c567b57a --- /dev/null +++ b/simman/files/getccid.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CCID^m" + waitfor 1 "+CCID: " + get 1 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getccid.sh b/simman/files/getccid.sh new file mode 100755 index 00000000..6c30c685 --- /dev/null +++ b/simman/files/getccid.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_CCID="/etc/simman/getccid.gcom" +SCRIPT_CICCID="/etc/simman/getciccid.gcom" +SCRIPT_CCID1="/etc/simman/getccid1.gcom" +device="" +CCID="" +proto="" +counter=0 + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getccid.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getccid.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +proto=$(uci -q get simman.core.proto) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + +if [ "$proto" = "0" ]; then + CCID=$(gcom -d $device -s $SCRIPT_CCID) +elif [ "$proto" = "3" ]; then + CCID=$(gcom -d $device -s $SCRIPT_CCID1) + [ -n "$CCID" ] && CCID="89${CCID//F/}" +else + CCID=$(gcom -d $device -s $SCRIPT_CICCID 2> /dev/null) + CCID=${CCID//F/} +fi +#CCID=$(gcom -d $device -s $SCRIPT_CCID | grep -e [0-9] | sed 's/"//g') +[ -z "$CCID" ] && CCID="NONE" + +echo $CCID + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi diff --git a/simman/files/getccid1.gcom b/simman/files/getccid1.gcom new file mode 100755 index 00000000..6054a75e --- /dev/null +++ b/simman/files/getccid1.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CCID^m" + waitfor 1 "89" + get 1 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getccidnb.gcom b/simman/files/getccidnb.gcom new file mode 100755 index 00000000..7030e5e0 --- /dev/null +++ b/simman/files/getccidnb.gcom @@ -0,0 +1,19 @@ +opengt + set com 9600n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + send "AT+NCCID^m" + waitfor 1 "+NCCID:" + if % = -1 goto error + if % = 0 goto continue + +:error + exit 1 + +:continue + get 1 "^m" $s + print $s + exit 0 diff --git a/simman/files/getciccid.gcom b/simman/files/getciccid.gcom new file mode 100755 index 00000000..97ddef67 --- /dev/null +++ b/simman/files/getciccid.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CICCID^m" + waitfor 1 "+ICCID: " + get 1 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getcsq.sh b/simman/files/getcsq.sh new file mode 100755 index 00000000..5904545b --- /dev/null +++ b/simman/files/getcsq.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_SIGLEV="/etc/simman/getsiglev.gcom" +device="" +SIGLEV=99 +SIGQUAL="" + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getsiglev.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getsiglev.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + + +SIGLEV=$(gcom -d $device -s $SCRIPT_SIGLEV | grep -e [0-9] | awk -F',' '{print $1}') +[ -z "$SIGLEV" ] && SIGLEV="99" + +echo "$SIGLEV" + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi + +exit 0 \ No newline at end of file diff --git a/simman/files/getenginfo.gcom b/simman/files/getenginfo.gcom new file mode 100755 index 00000000..0bede96e --- /dev/null +++ b/simman/files/getenginfo.gcom @@ -0,0 +1,30 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CENG=4,0^m" + waitfor 1 "OK" + send "AT+CENG?^m" + waitfor 1 "UMTS", "+CENG: 0," + if % = 0 goto umts + if % = 1 goto gsm + +:umts + waitfor 1 "+CENG: 0," + get 1 "^m" $s + print "UMTS:" + print $s + goto continue + +:gsm + get 1 "^m" $s + print "GSM:" + print $s + goto continue + +:continue + exit 0 diff --git a/simman/files/getgprsreg.gcom b/simman/files/getgprsreg.gcom new file mode 100755 index 00000000..5f5911c2 --- /dev/null +++ b/simman/files/getgprsreg.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CGREG?^m" + waitfor 1 "+CGREG: " + get 1 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getgprsreg.sh b/simman/files/getgprsreg.sh new file mode 100755 index 00000000..22cd112c --- /dev/null +++ b/simman/files/getgprsreg.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_GREG="/etc/simman/getgprsreg.gcom" +device="" +GREG="" + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getgprsreg.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getgprsreg.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + + +GREG=$(gcom -d $device -s $SCRIPT_GREG | grep -e [0-9] | awk -F',' '{print $2}') +[ -z "$GREG" ] && GREG="NONE" + + +if [ "$GREG" -eq 0 ]; then + echo "'NOT REGISTERED'" +else + if [ "$GREG" -eq 1 ]; then + echo "'REGISTERED, HOME'" + else + if [ "$GREG" -eq 2 ]; then + echo "'NOT REGISTERED, OPERATOR SEARCH'" + else + if [ "$GREG" -eq 3 ]; then + echo "'REGISTRATION DENIED'" + else + if [ "$GREG" -eq 5 ]; then + echo "'REGISTERED, ROAMING!'" + else + echo "'UNKNOWN'" + fi + fi + fi + fi +fi + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi + +exit 0 \ No newline at end of file diff --git a/simman/files/gethotswap.gcom b/simman/files/gethotswap.gcom new file mode 100755 index 00000000..e4a594ef --- /dev/null +++ b/simman/files/gethotswap.gcom @@ -0,0 +1,18 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+UIMHOTSWAPLEVEL?^m" + waitfor 1 "+UIMHOTSWAPLEVEL: " + get 1 "^m" $s + send "AT+UIMHOTSWAPON?^m" + waitfor 1 "+UIMHOTSWAPON: " + get 1 "^m" $t + print $s$t + +:continue + exit 0 diff --git a/simman/files/getimei.gcom b/simman/files/getimei.gcom new file mode 100755 index 00000000..cf384a74 --- /dev/null +++ b/simman/files/getimei.gcom @@ -0,0 +1,17 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "ATE1^m" + waitfor 1 "OK" + send "AT+CGSN^m" + waitfor 1 "CGSN" + get 1 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getimei.sh b/simman/files/getimei.sh new file mode 100755 index 00000000..9f09d047 --- /dev/null +++ b/simman/files/getimei.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_IMEI="/etc/simman/getimei.gcom" +device="" +IMEI="" +counter=0 + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getimei.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getimei.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + + IMEI=$(gcom -d $device -s $SCRIPT_IMEI) + +[ -z "$IMEI" ] && IMEI="NONE" + +echo $IMEI + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi diff --git a/simman/files/getimeinb.gcom b/simman/files/getimeinb.gcom new file mode 100644 index 00000000..e63a5fb2 --- /dev/null +++ b/simman/files/getimeinb.gcom @@ -0,0 +1,19 @@ +opengt + set com 9600n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + send "AT+CGSN=1^m" + waitfor 1 "+CGSN:" + if % = -1 goto error + if % = 0 goto continue + +:error + exit 1 + +:continue + get 1 "^m" $s + print $s + exit 0 diff --git a/simman/files/getnettype.sh b/simman/files/getnettype.sh new file mode 100755 index 00000000..22546997 --- /dev/null +++ b/simman/files/getnettype.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_BASESTINFO="/etc/simman/getbasestinfo.gcom" +SCRIPT_BASESTINFO1="/etc/simman/getenginfo.gcom" +SCRIPT_BASEIDINFO="/etc/simman/getbaseidinfo.gcom" +device="" +BASESTINFO="" +proto="" + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getbasestid.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getbasestid.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + +proto=$(uci -q get simman.core.proto) + +if [ "$proto" = "0" ]; then + BASESTINFO=$(gcom -d $device -s $SCRIPT_BASESTINFO | awk -F',' '{print $1}') + [ -z "$BASESTINFO" ] && BASESTINFO="NONE" +elif [ "$proto" = "3" ]; then + BASESTINFO=$(gcom -d $device -s $SCRIPT_BASESTINFO1 | awk -F':' '{print $1}') + [ -z "$BASESTINFO" ] && BASESTINFO="NONE" +else + BASESTINFO=$(gcom -d $device -s $SCRIPT_BASEIDINFO | awk -F',' '{print $1}') + [ -z "$BASESTINFO" ] && BASESTINFO="NONE" +fi + +echo $BASESTINFO + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi + +exit 0 diff --git a/simman/files/getpackinfo.gcom b/simman/files/getpackinfo.gcom new file mode 100755 index 00000000..60ff0a9a --- /dev/null +++ b/simman/files/getpackinfo.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT\^SIND="psinfo",2^m" + waitfor 2 "SIND: " + get 2 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getpackinfo.sh b/simman/files/getpackinfo.sh new file mode 100755 index 00000000..a4d21602 --- /dev/null +++ b/simman/files/getpackinfo.sh @@ -0,0 +1,140 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_PACKINFO="/etc/simman/getpackinfo.gcom" +SCRIPT_PACKINFO1="/etc/simman/getpackinfo1.gcom" +SCRIPT_PACKINFOLTE="/etc/simman/getpackinfolte.gcom" +device="" +PACKINFO="" +proto="" +counter=0 + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getpackinfo.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getpackinfo.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + +proto=$(uci -q get simman.core.proto) + +if [ "$proto" = "0" ]; then + PACKINFO=$(gcom -d $device -s $SCRIPT_PACKINFO | awk -F',' '{print $3}') + [ -z "$PACKINFO" ] && PACKINFO="NONE" + + if [ "$PACKINFO" -eq 0 ]; then + echo "'GPRS/EGPRS not available'" + else + if [ "$PACKINFO" -eq 2 ]; then + echo "'GPRS'" + else + if [ "$PACKINFO" -eq 4 ]; then + echo "'EGPRS'" + else + if [ "$PACKINFO" -eq 6 ]; then + echo "'WCDMA'" + else + if [ "$PACKINFO" -eq 8 ]; then + echo "'HSDPA'" + else + if [ "$PACKINFO" -eq 10 ]; then + echo "'HSDPA/HSUPA'" + else + echo "'UNKNOWN'" + fi + fi + fi + fi + fi + fi +elif [ "$proto" == "3" ]; then + PACKINFO=$(gcom -d $device -s $SCRIPT_PACKINFO1 | awk -F',' '{print $1}') + [ -z "$PACKINFO" ] && PACKINFO="NONE" + case "$PACKINFO" in + 0) + echo "'GSM'" + ;; + 1) + echo "'GPRS'" + ;; + 2) + echo "'WCDMA'" + ;; + 3) + echo "'EGPRS (EDGE)'" + ;; + 4) + echo "'HSDPA only(WCDMA)'" + ;; + 5) + echo "'HSUPA only(WCDMA)'" + ;; + 6) + echo "'HSPA (HSDPA and HSUPA, WCDMA)'" + ;; + 7) + echo "'LTE'" + ;; + esac +else + + PACKINFO=$(gcom -d $device -s $SCRIPT_PACKINFOLTE | awk -F',' '{print $2}') + + [ -z "$PACKINFO" ] && PACKINFO="NONE" + case "$PACKINFO" in + 0) + echo "'No service'" + ;; + 1) + echo "'GSM'" + ;; + 2) + echo "'GPRS'" + ;; + 3) + echo "'EGPRS (EDGE)'" + ;; + 4) + echo "'WCDMA'" + ;; + 5) + echo "'HSDPA only(WCDMA)'" + ;; + 6) + echo "'HSUPA only(WCDMA)'" + ;; + 7) + echo "'HSPA (HSDPA and HSUPA, WCDMA)'" + ;; + 8) + echo "'LTE'" + ;; + esac +fi + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi + +exit 0 \ No newline at end of file diff --git a/simman/files/getpackinfo1.gcom b/simman/files/getpackinfo1.gcom new file mode 100755 index 00000000..66b69669 --- /dev/null +++ b/simman/files/getpackinfo1.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CSACT?^m" + waitfor 2 "+CSACT: " + get 2 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getpackinfolte.gcom b/simman/files/getpackinfolte.gcom new file mode 100755 index 00000000..53e18f72 --- /dev/null +++ b/simman/files/getpackinfolte.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CNSMOD?^m" + waitfor 2 "+CNSMOD: " + get 2 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getpinstat.gcom b/simman/files/getpinstat.gcom new file mode 100755 index 00000000..a01bc413 --- /dev/null +++ b/simman/files/getpinstat.gcom @@ -0,0 +1,13 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 +:start + send "AT+CPIN?^m" + waitfor 1 "+CPIN:" + get 1 "^m" $s + print $s +:continue + exit 0 diff --git a/simman/files/getpinstat.sh b/simman/files/getpinstat.sh new file mode 100755 index 00000000..8da2b15d --- /dev/null +++ b/simman/files/getpinstat.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_PINSTAT="/etc/simman/getpinstat.gcom" +device="" +PINSTAT="" + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getpinstat.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getpinstat.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + +PINSTAT=$(gcom -d $device -s $SCRIPT_PINSTAT) +[ -z "$PINSTAT" ] && PINSTAT="NONE" + +echo $PINSTAT + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi + +exit 0 \ No newline at end of file diff --git a/simman/files/getreg.gcom b/simman/files/getreg.gcom new file mode 100755 index 00000000..88f7059f --- /dev/null +++ b/simman/files/getreg.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CREG?^m" + waitfor 2 "+CREG: " + get 1 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getreg.sh b/simman/files/getreg.sh new file mode 100755 index 00000000..ec876573 --- /dev/null +++ b/simman/files/getreg.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_REG="/etc/simman/getreg.gcom" +device="" +REG="" + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getreg.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getreg.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + +REG=$(gcom -d $device -s $SCRIPT_REG | awk -F',' '{print $2}') +[ -z "$REG" ] && REG="NONE" + +if [ "$REG" -eq 0 ]; then + echo "'NOT REGISTERED'" +else + if [ "$REG" -eq 1 ]; then + echo "'REGISTERED, HOME'" + else + if [ "$REG" -eq 2 ]; then + echo "'NOT REGISTERED, OPERATOR SEARCH'" + else + if [ "$REG" -eq 3 ]; then + echo "'REGISTRATION DENIED'" + else + if [ "$REG" -eq 5 ]; then + echo "'REGISTERED, ROAMING!'" + else + echo "'UNKNOWN'" + fi + fi + fi + fi +fi + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi diff --git a/simman/files/getsiglev.gcom b/simman/files/getsiglev.gcom new file mode 100755 index 00000000..4ead540d --- /dev/null +++ b/simman/files/getsiglev.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CSQ^m" + waitfor 1 "+CSQ: " + get 1 "^m" $s + print $s + +:continue + exit 0 diff --git a/simman/files/getsiglev.sh b/simman/files/getsiglev.sh new file mode 100755 index 00000000..6e9b263f --- /dev/null +++ b/simman/files/getsiglev.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_SIGLEV="/etc/simman/getsiglev.gcom" +device="" +SIGLEV=99 +SIGQUAL="" + +while getopts "h?d:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./getsiglev.sh [option]" + echo "Options:" + echo " -d - AT modem device" + echo "Example: getsiglev.sh -d /dev/ttyACM3" + exit 0 + ;; + d) device=$OPTARG + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +# Check if device exists +[ ! -e $device ] && exit 0 + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + + +SIGLEV=$(gcom -d $device -s $SCRIPT_SIGLEV | grep -e [0-9] | awk -F',' '{print $1}') +[ -z "$SIGLEV" ] && SIGLEV="NONE" + + +if [ "$SIGLEV" -lt 10 ]; then + echo "'$SIGLEV ASU (BAD)'" +else + if [ "$SIGLEV" -lt 13 ]; then + echo "'$SIGLEV ASU (NORMAL)'" + else + if [ "$SIGLEV" -lt 18 ]; then + echo "'$SIGLEV ASU (GOOD)'" + else + if [ "$SIGLEV" -lt 32 ]; then + echo "'$SIGLEV ASU (EXCELLENT)'" + else + echo "'NO SIGNAL'" + fi + fi + fi +fi + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi + +exit 0 \ No newline at end of file diff --git a/simman/files/getsimcheck.sh b/simman/files/getsimcheck.sh new file mode 100755 index 00000000..5dd0d613 --- /dev/null +++ b/simman/files/getsimcheck.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +GPIO_PATH=/sys/class/gpio + +SIMADDR_PIN=$(uci -q get simman.core.simaddr_gpio_pin) +[ -z "$SIMADDR_PIN" ] && { + logger -t $tag "Not set SIMADDR_PIN" && exit 0 +} + +SIMDET0_PIN=$(uci -q get simman.core.simdet0_gpio_pin) +[ -z "$SIMDET0_PIN" ] && { + logger -t $tag "Not set SIMDET0_PIN" && exit 0 +} + +SIMDET1_PIN=$(uci -q get simman.core.simdet1_gpio_pin) +[ -z "$SIMDET1_PIN" ] && { + logger -t $tag "Not set SIMDET1_PIN" && exit 0 +} + +if [ ! -d "$GPIO_PATH/gpio$SIMADDR_PIN" ]; then + echo $SIMADDR_PIN > $GPIO_PATH/export + echo out > $GPIO_PATH/gpio$SIMADDR_PIN/direction + logger -t $tag "Exporting gpio$SIMADDR_PIN" +fi + +if [ ! -d "$GPIO_PATH/gpio$SIMDET0_PIN" ]; then + echo $SIMDET0_PIN > $GPIO_PATH/export + echo in > $GPIO_PATH/gpio$SIMDET0_PIN/direction + logger -t $tag "Exporting gpio$SIMDET0_PIN" +fi + +if [ ! -d "$GPIO_PATH/gpio$SIMDET1_PIN" ]; then + echo $SIMDET1_PIN > $GPIO_PATH/export + echo in > $GPIO_PATH/gpio$SIMDET1_PIN/direction + logger -t $tag "Exporting gpio$SIMDET1_PIN" +fi + +sim1=$(cat $GPIO_PATH/gpio$SIMDET0_PIN/value) +sim2=$(cat $GPIO_PATH/gpio$SIMDET1_PIN/value) +simaddr=$(cat $GPIO_PATH/gpio$SIMADDR_PIN/value) + +#sim1act="" +#sim2act="" +#sim1av="" +#sim2av="" + +if [ "$sim1" == "1" ]; then + sim1av="NOT INSERTED" +else + sim1av="INSERTED" +fi +if [ "$sim2" == "1" ]; then + sim2av="NOT INSERTED" +else + sim2av="INSERTED" +fi +if [ "$simaddr" == "1" ]; then + sim2act=" (ACT)" +else + sim1act=" (ACT)" +fi + +echo "'1 $sim1av$sim1act | 2 $sim2av$sim2act'" \ No newline at end of file diff --git a/simman/files/gpsdata.gcom b/simman/files/gpsdata.gcom new file mode 100644 index 00000000..478594b5 --- /dev/null +++ b/simman/files/gpsdata.gcom @@ -0,0 +1,19 @@ +opengt + set com 9600n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + waitfor 5 "$G" + if % = -1 goto timeout + if % = 0 goto continue + +:timeout + print "ERROR" + exit 1 + +:continue + get 1 "^m" $s + print $s + exit 0 diff --git a/simman/files/gpson.gcom b/simman/files/gpson.gcom new file mode 100755 index 00000000..e8df67ef --- /dev/null +++ b/simman/files/gpson.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CGPS=1^m" + waitfor 2 "OK" + send "AT+CGPSAUTO=1^m" + waitfor 2 "OK" + +:continue + exit 0 diff --git a/simman/files/nbinfo.sh b/simman/files/nbinfo.sh new file mode 100755 index 00000000..b1938ab6 --- /dev/null +++ b/simman/files/nbinfo.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +DEVICE="/dev/ttyAMA0" + +send_at(){ + IMEI="$(gcom -d $DEVICE -s /etc/simman/sendat.gcom)" + if [[ "$?" != "0" ]]; then + echo "Not available" + exit 1 + fi +} + +imei(){ + IMEI="$(gcom -d $DEVICE -s /etc/simman/getimeinb.gcom)" + if [[ "$?" != "0" ]]; then + echo "Not available" + exit 1 + fi + echo $IMEI +} + +setfun(){ + FUN=$(COMMAND="?" gcom -d /dev/ttyAMA0 -s /etc/simman/setfunnb.gcom) + if [[ "$FUN" == "0" ]]; then + FUN=$(COMMAND="=1" gcom -d /dev/ttyAMA0 -s /etc/simman/setfunnb.gcom) + sleep 1 + else + FUN=$(COMMAND="=0" gcom -d /dev/ttyAMA0 -s /etc/simman/setfunnb.gcom) + FUN=$(COMMAND="=1" gcom -d /dev/ttyAMA0 -s /etc/simman/setfunnb.gcom) + sleep 1 + fi +} + +ccid(){ + CCID="$(gcom -d $DEVICE -s /etc/simman/getccidnb.gcom)" + if [[ "$?" != "0" ]]; then + echo "Not available" + exit 1 + fi + echo $CCID +} + +imsi(){ + CCID="$(gcom -d $DEVICE -s /etc/simman/getccidnb.gcom)" + if [[ "$?" != "0" ]]; then + echo "Not available" + exit 1 + fi + echo $CCID +} + +case "$1" in + imei) + eval send_at + eval imei + exit 0 + ;; + ccid) + eval send_at + eval setfun + eval ccid + exit 0 + ;; + imsi) + eval send_at + eval setfun + eval imsi + exit 0 + ;; + *) + logger -st nbinfo "Command is not supported. Use the following commands: imei ccid imsi" + exit 0 + ;; +esac diff --git a/simman/files/scmux.hotplug b/simman/files/scmux.hotplug new file mode 100755 index 00000000..e5df3de1 --- /dev/null +++ b/simman/files/scmux.hotplug @@ -0,0 +1,99 @@ +SIM7100="1e0e/9001/232" +SIM7600="1e0e/9001/318" +SIM5360="5c6/9000/0" +EHS5="1e2d/58/1730" +SIM5300="1e0e/20/1730" + +case "$ACTION" in + add) + #echo "ADDED: PRODUCT: $PRODUCT, TYPE: $TYPE, DEVPATH: $DEVPATH, INTERFACE: $INTERFACE" >> /tmp/foo.log + if [ "$PRODUCT" = "$SIM7100" -o "$PRODUCT" = "$SIM7600" ];then + if [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.2" ]; then + DEVICE_NAME=$(ls /sys$DEVPATH | grep tty) + CHECK=$(gcom -d /dev/$DEVICE_NAME -s /etc/simman/gethotswap.gcom) + if [ "$CHECK" != "11" ]; then + gcom -d /dev/$DEVICE_NAME -s /etc/simman/sethotswap.gcom + echo 1 > /sys/class/gpio/gpio83/value + sleep 1 + echo 0 > /sys/class/gpio/gpio83/value + dev=$(ls /dev/ | grep cdc-wdm) + while [ -z "$dev"]; do + sleep 4 + dev=$(ls /dev/ | grep cdc-wdm) + done + exit 0 + else + ln -s /dev/$DEVICE_NAME /dev/ttyGSM1 + ln -s /dev/$DEVICE_NAME /dev/ttyGSM2 + exit 0 + fi + fi + if [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.3" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.3" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.3" ]; then + DEVICE_NAME=$(ls /sys$DEVPATH | grep tty) + ln -s /dev/$DEVICE_NAME /dev/ttyGSM3 + exit 0 + fi + fi + + if [ "$PRODUCT" = "$EHS5" ];then + if [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.6" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.6" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.6" ]; then + DEVICE_NAME=$(ls /sys$DEVPATH/tty | grep tty) + ln -s /dev/$DEVICE_NAME /dev/ttyGSM1 + ln -s /dev/$DEVICE_NAME /dev/ttyGSM2 + exit 0 + fi + if [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.8" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.8" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.8" ]; then + DEVICE_NAME=$(ls /sys$DEVPATH/tty | grep tty) + ln -s /dev/$DEVICE_NAME /dev/ttyGSM3 + exit 0 + fi + fi + + if [ "$PRODUCT" = "$SIM5300" ];then + if [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.6" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.6" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.6" ]; then + DEVICE_NAME=$(ls /sys$DEVPATH/tty | grep tty) + ln -s /dev/$DEVICE_NAME /dev/ttyGSM1 + ln -s /dev/$DEVICE_NAME /dev/ttyGSM2 + ln -s /dev/$DEVICE_NAME /dev/ttyGSM3 + exit 0 + fi + fi + + if [ "$PRODUCT" = "$SIM5360" ];then + if [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.2" ]; then + DEVICE_NAME=$(ls /sys$DEVPATH | grep tty) + ln -s /dev/$DEVICE_NAME /dev/ttyGSM1 + ln -s /dev/$DEVICE_NAME /dev/ttyGSM2 + exit 0 + fi + if [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.3" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.3" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.3" ]; then + DEVICE_NAME=$(ls /sys$DEVPATH | grep tty) + ln -s /dev/$DEVICE_NAME /dev/ttyGSM3 + exit 0 + fi + fi + ;; + + remove) + if [ "$PRODUCT" = "$SIM7100" -o "$PRODUCT" = "$SIM7600" -o "$PRODUCT" = "$EHS5" -o "$PRODUCT" = "$SIM5300" -o "$PRODUCT" = "$SIM5360" ]; then + rm /dev/ttyGSM1 + rm /dev/ttyGSM2 + rm /dev/ttyGSM3 + exit 0 + fi + ;; +esac diff --git a/simman/files/sendat.gcom b/simman/files/sendat.gcom new file mode 100755 index 00000000..368f9564 --- /dev/null +++ b/simman/files/sendat.gcom @@ -0,0 +1,19 @@ +opengt + set com 9600n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + send "AT^m" + waitfor 1 "OK" + if % = -1 goto error + if % = 0 goto continue + +:error + exit 1 + +:continue + get 1 "^m" $s + print $s + exit 0 diff --git a/simman/files/setfun.gcom b/simman/files/setfun.gcom new file mode 100755 index 00000000..d7c8f5f7 --- /dev/null +++ b/simman/files/setfun.gcom @@ -0,0 +1,21 @@ +opengt + set com 115200n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + send "AT+CFUN" + send $env("COMMAND") + send "^m" + waitfor 3 "OK","+CFUN: " + if % = 0 goto continue + if % = 1 goto request + +:request + get 1 "^m" $s + print $s + exit 0 + +:continue + exit 0 diff --git a/simman/files/setfun.sh b/simman/files/setfun.sh new file mode 100755 index 00000000..773c456f --- /dev/null +++ b/simman/files/setfun.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +OPTIND=1 + +SCRIPT_CFUN="/etc/simman/setfun.gcom" +device="" +IMEI="" +counter=0 + +while getopts "h?f:" opt; do + case "$opt" in + h|\?) + echo "Usage: ./setfun.sh [option]" + echo "Options:" + echo " -f - CFUN mode" + echo "Example: setfun.sh -f 0" + exit 0 + ;; + f) cfun=$OPTARG + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$device" ] && device=$(uci -q get simman.core.atdevice) + +PROTO_3G=$(uci get simman.core.proto 2>/dev/null) +if [ "$PROTO_3G" = "3" ];then + echo "ALL:" > /tmp/lock/smsd.lock +fi + +# Check if device exists +[ ! -e $device ] && exit 0 +while [ "$RESULT" != "$cfun" ]; do + RESULT=$(COMMAND="=$cfun" gcom -d $device -s $SCRIPT_CFUN) + sleep 1 + RESULT=$(COMMAND="?" gcom -d $device -s $SCRIPT_CFUN) +done + +if [ "$PROTO_3G" = "3" ];then + rm /tmp/lock/smsd.lock +fi + +exit 0 \ No newline at end of file diff --git a/simman/files/setfunnb.gcom b/simman/files/setfunnb.gcom new file mode 100755 index 00000000..fe7f79a1 --- /dev/null +++ b/simman/files/setfunnb.gcom @@ -0,0 +1,21 @@ +opengt + set com 9600n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + send "AT+CFUN" + send $env("COMMAND") + send "^m" + waitfor 3 "OK","+CFUN:" + if % = 0 goto continue + if % = 1 goto request + +:request + get 1 "^m" $s + print $s + exit 0 + +:continue + exit 0 diff --git a/simman/files/sethotswap.gcom b/simman/files/sethotswap.gcom new file mode 100755 index 00000000..13a36542 --- /dev/null +++ b/simman/files/sethotswap.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+UIMHOTSWAPLEVEL=1^m" + waitfor 2 "OK" + send "AT+UIMHOTSWAPON=1^m" + waitfor 2 "OK" + +:continue + exit 0 diff --git a/simman/files/setsim.sh b/simman/files/setsim.sh new file mode 100755 index 00000000..b1820499 --- /dev/null +++ b/simman/files/setsim.sh @@ -0,0 +1,325 @@ +#!/bin/sh + +OPTIND=1 + +GPIO_PATH=/sys/class/gpio +CONFIG_DIR=/etc/simman +tag=simman + +sim="" +mode="" +pow="" + +while getopts "h?s:mp" opt; do + case "$opt" in + h|\?) + echo "Usage: ./setsim.sh [option]" + echo "Options:" + echo " -s - number sim card, 0 - SIM1 1 - SIM2" + echo " -m - without SIMDET_PIN pushed" + echo " -p - modem power down" + echo "Example: ./setsim.sh -s 1" + exit 0 + ;; + s) sim=$OPTARG + ;; + m) mode="1" + ;; + p) pow="1" + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$sim" ] && { + sim="0" +} + +[ -z "$mode" ] && { + mode="0" +} + +[ -z "$pow" ] && { + pow="0" +} + +# read GPIO configuration +PWRKEY_PIN=$(uci -q get simman.core.pwrkey_gpio_pin) +[ -z "$PWRKEY_PIN" ] && { + logger -t $tag "Not set PWRKEY_PIN" && exit 0 +} + +GSMPOW_PIN=$(uci -q get simman.core.gsmpow_gpio_pin) +[ -z "$GSMPOW_PIN" ] && { + logger -t $tag "Not set GSMPOW_PIN" && exit 0 +} + +SIMDET_PIN=$(uci -q get simman.core.simdet_gpio_pin) +[ -z "$SIMDET_PIN" ] && { + logger -t $tag "Not set SIMDET_PIN" && exit 0 +} + +SIMADDR_PIN=$(uci -q get simman.core.simaddr_gpio_pin) +[ -z "$SIMADDR_PIN" ] && { + logger -t $tag "Not set SIMADDR_PIN" && exit 0 +} + +SIMDET0_PIN=$(uci -q get simman.core.simdet0_gpio_pin) +[ -z "$SIMDET0_PIN" ] && { + logger -t $tag "Not set SIMDET0_PIN" && exit 0 +} + +SIMDET1_PIN=$(uci -q get simman.core.simdet1_gpio_pin) +[ -z "$SIMDET1_PIN" ] && { + logger -t $tag "Not set SIMDET1_PIN" && exit 0 +} + +ATDEVICE=$(uci -q get simman.core.atdevice) +[ -z "$ATDEVICE" ] && { + logger -t $tag "Not set ATDEVICE" && exit 0 +} + +GPSPORT=$(uci -q get simman.core.gpsdevice) + +# GPIO ports configure +if [ ! -d "$GPIO_PATH/gpio$GSMPOW_PIN" ]; then + echo $GSMPOW_PIN > $GPIO_PATH/export + echo out > $GPIO_PATH/gpio$GSMPOW_PIN/direction + logger -t $tag "Exporting gpio$GSMPOW_PIN" +fi + +if [ ! -d "$GPIO_PATH/gpio$SIMDET_PIN" ]; then + echo $SIMDET_PIN > $GPIO_PATH/export + echo out > $GPIO_PATH/gpio$SIMDET_PIN/direction + logger -t $tag "Exporting gpio$SIMDET_PIN" +fi + +if [ ! -d "$GPIO_PATH/gpio$SIMADDR_PIN" ]; then + echo $SIMADDR_PIN > $GPIO_PATH/export + echo out > $GPIO_PATH/gpio$SIMADDR_PIN/direction + logger -t $tag "Exporting gpio$SIMADDR_PIN" +fi + +if [ ! -d "$GPIO_PATH/gpio$SIMDET0_PIN" ]; then + echo $SIMDET0_PIN > $GPIO_PATH/export + echo in > $GPIO_PATH/gpio$SIMDET0_PIN/direction + logger -t $tag "Exporting gpio$SIMDET0_PIN" +fi + +if [ ! -d "$GPIO_PATH/gpio$SIMDET1_PIN" ]; then + echo $SIMDET1_PIN > $GPIO_PATH/export + echo in > $GPIO_PATH/gpio$SIMDET1_PIN/direction + logger -t $tag "Exporting gpio$SIMDET1_PIN" +fi + +# modem type: 0 - Telit; 1 - Simcom +proto=$(uci -q get simman.core.proto) +[ -z "$proto" ] && { + logger -t $tag "Not set modem type" && exit 0 +} +# find 3g interface +iface=$(uci show network | awk "/proto='3g'|proto='qmi'/" | awk -F'.' '{print $2}') + +[ -z "$iface" ] && logger -t $tag "Not found 3g/4g interface" && exit 0 + +# Check if SIM card placed in holder +sim1=$(cat $GPIO_PATH/gpio$SIMDET0_PIN/value) +sim2=$(cat $GPIO_PATH/gpio$SIMDET1_PIN/value) +ac_sim=$(cat /tmp/simman/sim) + +if [ "$sim1" == "1" ] && [ "$sim2" == "1" ]; then + logger -t $tag "Both SIM cards are not inserted" + [ "$ac_sim" != "0" ] && echo 0 > /tmp/simman/sim + # release SIM_DET pin + echo "0" > $GPIO_PATH/gpio$SIMDET_PIN/value + ubus call network.interface.$iface down + exit 0 +fi + +if [ "$pow" != "1" ]; then +[ "$sim" == "0" ] && { + [ "$sim1" == "1" ] && logger -t $tag "Not inserted sim 1" && exit 0 + [ "$ac_sim" == "1" ] && ubus call network.interface.$iface down && logger -t $tag "SIM 1 is already active" && ubus call network.interface.$iface up && exit 0 + logger -t $tag "Set SIM card 1" +} + +[ "$sim" == "1" ] && { + [ "$sim2" == "1" ] && logger -t $tag "Not inserted sim 2" && exit 0 + [ "$ac_sim" == "2" ] && ubus call network.interface.$iface down && logger -t $tag "SIM 2 is already active" && ubus call network.interface.$iface up && exit 0 + logger -t $tag "Set SIM card 2" +} +else + [ "$sim" == "0" ] && [ "$sim1" == "1" ] && sim="1" + [ "$sim" == "1" ] && [ "$sim2" == "1" ] && sim="0" +fi + +# set down 3g interface +ubus call network.interface.$iface down + +# setting new apn, GPRS settings (pincode, user name, password) +apn=$(uci -q get simman.@sim$sim[0].GPRS_apn) +if [ -z "$apn" ]; then + uci -q delete network.$iface.apn +else + uci -q set network.$iface.apn=$apn +fi + +pin=$(uci -q get simman.@sim$sim[0].pin) +if [ -z "$pin" ]; then + uci -q delete network.$iface.pincode +else + uci -q set network.$iface.pincode=$pin +fi + +user=$(uci -q get simman.@sim$sim[0].GPRS_user) +if [ -z "$user" ]; then + uci -q delete network.$iface.username +else + uci -q set network.$iface.username=$user +fi + +pass=$(uci -q get simman.@sim$sim[0].GPRS_pass) +if [ -z "$pass" ]; then + uci -q delete network.$iface.password +else + uci -q set network.$iface.password=$pass +fi + +/etc/init.d/smstools3 stop &> /dev/null & + +sleep 1 + +# at+cfun=0 for SIM5300 +if [ "$proto" == "3" -a "$pow" -ne "1" ]; then + $CONFIG_DIR/setfun.sh -f 0 +fi + +# power down for SIM5360 +if [ "$proto" == "2" -a "$pow" -ne "1" ]; then + dev=$(ls $ATDEVICE 2>/dev/null) + if [ -n "$dev" ]; then + logger -t $tag "power down for SIM5360" + /etc/init.d/smstools3 stop > /dev/null & + echo "0" > $GPIO_PATH/gpio$PWRKEY_PIN/value + sleep 1 + echo "1" > $GPIO_PATH/gpio$PWRKEY_PIN/value + sleep 3 + dev=$(ls $ATDEVICE 2>/dev/null) + while [ ! -z "$dev" ]; do + sleep 4 + dev=$(ls $ATDEVICE 2>/dev/null) + done + fi +fi + +# Set sim card +if [ "$mode" == "0" ]; then + echo "0" > $GPIO_PATH/gpio$SIMDET_PIN/value + + sleep 1 + + # Power switch + if [ "$pow" == "1" ]; then + + logger -t $tag "Reset pin toggle" + + if [ -n "$GPSPORT" -a "$GPSPORT" != "/dev/ttyAPP1" ]; then + /etc/init.d/gpsd stop + /etc/init.d/ntpd stop + fi + + # release SIMADDR + echo "0" > $GPIO_PATH/gpio$SIMADDR_PIN/value + + sleep 2 + # power down + echo "1" > $GPIO_PATH/gpio$GSMPOW_PIN/value + + sleep 2 + + # power up + echo "0" > $GPIO_PATH/gpio$GSMPOW_PIN/value + + sleep 4 + + dev=$(ls $ATDEVICE 2>/dev/null) + while [ -z "$dev" ]; do + sleep 4 + dev=$(ls $ATDEVICE 2>/dev/null) + done + sim="0" + + else + retry=0 + + + + while [ $retry -lt 10 -a "$proto" != "2" ]; do + retry=`expr $retry + 1` + + reg=$($CONFIG_DIR/getreg.sh) + + [ "$reg" == "'UNKNOWN'" ] || [ "$reg" == "'NOT REGISTERED'" ] || [ "$reg" == "NONE" ] && break + + logger -t $tag "retry #$retry reading CREG, now registration status $reg" + + sleep 1 + done + fi +fi + +if [ "$sim" == "1" ]; then + echo "1" > $GPIO_PATH/gpio$SIMADDR_PIN/value + echo "2" > /tmp/simman/sim +else + echo "0" > $GPIO_PATH/gpio$SIMADDR_PIN/value + echo "1" > /tmp/simman/sim +fi + +sleep 1 + +if [ "$mode" == "0" ]; then + echo "1" > $GPIO_PATH/gpio$SIMDET_PIN/value +fi + +# at+cfun=1 for SIM5300 +if [ "$proto" == "3" -a "$pow" -ne "1" ]; then + $CONFIG_DIR/setfun.sh -f 1 +fi +# power up for SIM5360 +if [ "$proto" == "2" -a "$pow" -ne "1" ]; then + logger -t $tag "power up for SIM5360" + counter=0 + echo "0" > $GPIO_PATH/gpio$PWRKEY_PIN/value + usleep 50000 + echo "1" > $GPIO_PATH/gpio$PWRKEY_PIN/value + sleep 3 + dev=$(ls $ATDEVICE 2>/dev/null) + while [ -z "$dev" ]; do + sleep 2 + dev=$(ls $ATDEVICE 2>/dev/null) + counter=$(($counter + 1)) + if [ "$counter" == "15" ]; then + echo "0" > $GPIO_PATH/gpio$PWRKEY_PIN/value + usleep 50000 + echo "1" > $GPIO_PATH/gpio$PWRKEY_PIN/value + counter=0 + fi + done + logger -t $tag "SIM5360 powered up" +fi + +sleep 10 && /etc/init.d/smstools3 restart &> /dev/null & + +# store uci changes +uci commit + +# network reload +ubus call network reload + +# reload +ubus call network.interface.$iface up + +exit 0 diff --git a/simman/files/simman.config b/simman/files/simman.config new file mode 100755 index 00000000..6cf04b36 --- /dev/null +++ b/simman/files/simman.config @@ -0,0 +1,55 @@ +config simman core + option enabled '1' + option only_first_sim '0' + option retry_num '3' + option check_period '60' + option delay '6000' + option testip '8.8.8.8 8.8.4.4' + option atdevice '/dev/ttyGSM1' + option gpsdevice '' + option iface 'wwan0' + option sw_before_modres '3' + option sw_before_sysres '0' + option sim '' + option imei 'NONE' + option ccid 'NONE' + option proto '0' + option pwrkey_gpio_pin '105' + option gsmpow_gpio_pin '83' + option simdet_gpio_pin '78' + option simaddr_gpio_pin '82' + option simdet0_gpio_pin '79' + option simdet1_gpio_pin '104' + option csq_level '0' + +config simman info + option atdevice '/dev/ttyGSM2' + option sim 'NONE' + option imei 'NONE' + option ccid 'NONE' + option pincode_stat 'NONE' + option sig_lev 'NONE' + option reg_stat 'NONE' + option base_st_id 'NONE' + option base_st_bw 'NONE' + option net_type 'NONE' + option gprs_reg_stat 'NONE' + option pack_type 'NONE' + +config sim0 + option priority '1' + option pin '' + option GPRS_user '' + option GPRS_pass '' + option GPRS_apn 'internet' + option testip '' + +config sim1 + option priority '0' + option pin '' + option GPRS_user '' + option GPRS_pass '' + option GPRS_apn 'internet' + option testip '' + +config nbiot diff --git a/simman/files/simman.hotplug b/simman/files/simman.hotplug new file mode 100755 index 00000000..7f45491b --- /dev/null +++ b/simman/files/simman.hotplug @@ -0,0 +1,145 @@ +case "$ACTION" in + add) + #echo "ADDED: PRODUCT: $PRODUCT, TYPE: $TYPE, DEVPATH: $DEVPATH, INTERFACE: $INTERFACE" >> /tmp/foo.log + version=$(cat /etc/banner | grep "RTU" | awk -F' ' '{print $3}') + + SIM7100="1e0e/9001/232" + SIM7600="1e0e/9001/318" + SIM5360="5c6/9000/0" + EHS5="1e2d/58/1730" + SIM5300="1e0e/20/1730" + + case "$PRODUCT" in + $SIM7100) + if [ "$version" = "RTUx68V2" -o "$version" = "RTU968V2" ] \ + && [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.2" ]; then + + sed -i -e "s/devices = SIM5360/devices = mobile/g" /etc/smsd.conf + uci delete network.internet + uci set network.wwan0=interface + uci set network.wwan0.proto=qmi + uci set network.wwan0.device=/dev/cdc-wdm0 + uci set network.wwan0.apn=internet + uci set network.wwan0.autoconnect=0 + uci set network.wwan0.metric=2 + uci set simman.core.iface=wwan0 + uci set simman.core.proto=1 + echo wwan0 > /sys/class/leds/middle\:net/device_name + echo wwan0 > /sys/class/leds/bottom\:act/device_name + sed -i -e "s/$version/RTU1068V2/g" /etc/banner + sed -i -e "s/$version/RTU1068V2/g" /etc/config/system + sed -i -e "s/3g-internet/wwan0/g" /etc/config/system + uci commit + fi + ;; + + $SIM7600) + if [ "$version" = "RTUx68V2" -o "$version" = "RTU968V2" ] \ + && [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.2" ]; then + + sed -i -e "s/devices = SIM5360/devices = mobile/g" /etc/smsd.conf + uci delete network.internet + uci set network.wwan0=interface + uci set network.wwan0.proto=qmi + uci set network.wwan0.device=/dev/cdc-wdm0 + uci set network.wwan0.apn=internet + uci set network.wwan0.autoconnect=0 + uci set network.wwan0.metric=2 + uci set simman.core.iface=wwan0 + uci set simman.core.proto=1 + echo wwan0 > /sys/class/leds/middle\:net/device_name + echo wwan0 > /sys/class/leds/bottom\:act/device_name + sed -i -e "s/$version/RTU1068V2/g" /etc/banner + sed -i -e "s/$version/RTU1068V2/g" /etc/config/system + sed -i -e "s/3g-internet/wwan0/g" /etc/config/system + uci commit + fi + ;; + + $EHS5) + PROTO_3G=$(uci get simman.core.proto 2>/dev/null) + if [ "$version" = "RTUx68V2" -o "$version" = "RTU1068V2" -o "$PROTO_3G" != "0" ] \ + && [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.2" ]; then + + sed -i -e "s/devices = SIM5360/devices = mobile/g" /etc/smsd.conf + uci delete network.wwan0 + uci set network.internet=interface + uci set network.internet.proto=3g + uci set network.internet.device=/dev/ttyACM0 + uci set network.internet.service=umts + uci set network.internet.apn=internet + uci set network.internet.metric=2 + uci set simman.core.iface=3g-internet + uci set simman.core.proto=0 + echo 3g-internet > /sys/class/leds/middle\:net/device_name + echo 3g-internet > /sys/class/leds/bottom\:act/device_name + sed -i -e "s/$version/RTU968V2/g" /etc/banner + sed -i -e "s/$version/RTU968V2/g" /etc/config/system + sed -i -e "s/wwan0/3g-internet/g" /etc/config/system + uci commit + ubus call network reload + fi + ;; + + $SIM5360) + PROTO_3G=$(uci get simman.core.proto 2>/dev/null) + if [ "$version" = "RTUx68V2" -o "$version" = "RTU1068V2" -o "$PROTO_3G" != "2" ] \ + && [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.2" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.3/1-1.3:1.2" ]; then + uci delete network.wwan0 + sed -i -e "s/devices = mobile/devices = SIM5360/g" /etc/smsd.conf + uci delete network.internet + uci set network.wwan0=interface + uci set network.wwan0.proto=qmi + uci set network.wwan0.device=/dev/cdc-wdm0 + uci set network.wwan0.apn=internet + uci set network.wwan0.autoconnect=0 + uci set network.wwan0.metric=2 + uci set simman.core.iface=wwan0 + uci set simman.core.proto=2 + echo wwan0 > /sys/class/leds/middle\:net/device_name + echo wwan0 > /sys/class/leds/bottom\:act/device_name + sed -i -e "s/$version/RTU968V2/g" /etc/banner + sed -i -e "s/$version/RTU968V2/g" /etc/config/system + sed -i -e "s/3g-internet/wwan0/g" /etc/config/system + uci commit + fi + ;; + + $SIM5300) + PROTO_3G=$(uci get simman.core.proto 2>/dev/null) + if [ "$version" = "RTUx68V2" -o "$version" = "RTU1068V2" -o "$PROTO_3G" != "3" ] \ + && [ "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1:1.6" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1.1/1-1.1:1.6" \ + -o "$DEVPATH" = "/devices/soc0/80080000.ahb/80090000.usb/ci_hdrc.1/usb1/1-1/1-1./1-1.3:1.6" \]; then + sed -i -e "s/devices = SIM5360/devices = mobile/g" /etc/smsd.conf + uci delete network.wwan0 + uci set network.internet=interface + uci set network.internet.proto=3g + uci set network.internet.device=/dev/ttyACM0 + uci set network.internet.service=umts + uci set network.internet.apn=internet + uci set network.internet.metric=2 + uci set simman.core.iface=3g-internet + uci set simman.core.proto=3 + echo 3g-internet > /sys/class/leds/middle\:net/device_name + echo 3g-internet > /sys/class/leds/bottom\:act/device_name + sed -i -e "s/\\\^S/+X/g" /etc/chatscripts/3g.chat + sed -i -e "s/$version/RTU968V2/g" /etc/banner + sed -i -e "s/$version/RTU968V2/g" /etc/config/system + sed -i -e "s/wwan0/3g-internet/g" /etc/config/system + uci commit + ubus call network reload + fi + ;; + esac + sync + ;; +esac diff --git a/simman/files/simman.init b/simman/files/simman.init new file mode 100755 index 00000000..4142f4eb --- /dev/null +++ b/simman/files/simman.init @@ -0,0 +1,78 @@ +#!/bin/sh /etc/rc.common + +START=99 +STOP=10 +USE_PROCD=1 + +DIR=/sbin +PROG=simman + +error(){ + echo "${initscript}:" "$@" 1>&2 +} + +xappend() { + local filename="$1" + local value="$2" + echo "${value#--}" >> "$filename" +} + +section_enabled(){ + config_get_bool enabled "$1" 'enabled' 0 + [ $enabled -gt 0 ] +} + +start_service_daemon(){ + local s="$1" + + section_enabled "$s" || return 1 + if [[ -e "/tmp/simman" ]]; then + rm /tmp/simman/* &>/dev/null + else + mkdir /tmp/simman + echo "0" > /tmp/simman/sim + echo "NONE" > /tmp/simman/imei + fi + + uci set simman.core.sim='0' + uci set simman.core.imei='NONE' + uci set simman.core.ccid='NONE' + uci set simman.info.iface='wan2' + uci set simman.info.sim='NONE' + uci set simman.info.imei='NONE' + uci set simman.info.ccid='NONE' + uci set simman.info.pincode_stat='NONE' + uci set simman.info.sig_lev='NONE' + uci set simman.info.reg_stat='NONE' + uci set simman.info.base_st_id='NONE' + uci set simman.info.base_st_bw='NONE' + uci set simman.info.net_type='NONE' + uci set simman.info.gprs_reg_stat='NONE' + uci set simman.info.pack_type='NONE' + uci commit simman + + procd_open_instance + procd_set_param command "$DIR/$PROG" + procd_set_param respawn ${respawn_threshold:-360} ${respawn_timeout:-5} ${respawn_retry:-0} + procd_close_instance +} + +start_service(){ + config_load 'simman' + config_foreach start_service_daemon 'simman' +} + +service_triggers() +{ + procd_add_reload_trigger "simman" +} + +stop(){ + service_stop $DIR/$PROG +} + +reload_service() { + service_stop $DIR/$PROG + config_load 'simman' + config_foreach start_service_daemon 'simman' +} diff --git a/simman/src/Makefile b/simman/src/Makefile new file mode 100755 index 00000000..876f4cff --- /dev/null +++ b/simman/src/Makefile @@ -0,0 +1,22 @@ +STAG_DIR = ./../../../staging_dir/target-arm_arm926ej-s_uClibc-0.9.33.2_eabi +CC = gcc +CFLAGS = -Os -Wall -Wmissing-declarations -g3 +CPPFLAGS = -I../inc -I./ -I$(STAG_DIR)/usr/include +LDFLAGS = -L$(STAG_DIR)/usr/lib -L./ + +LDLIBS = -luci + +PROGRAMS=simman simman_getinfo + +all: $(PROGRAMS) + +simman: simman.o common.o + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +simman_getinfo: simman_getinfo.o common.o + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +clean: + rm -f *.o $(PROGRAMS) + + diff --git a/simman/src/common.c b/simman/src/common.c new file mode 100755 index 00000000..c401d033 --- /dev/null +++ b/simman/src/common.c @@ -0,0 +1,549 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "dirent.h" +#include "uci.h" +#include + +#include "log.h" + +void execCommandNoWait(char **cmd) { + // Create a child process from current (?) + pid_t varProcess = fork(); + + // if fork successfully created + if (!varProcess) { + // Execute command + execvp(*cmd, cmd); + } + + // Wait for command closing + waitpid(varProcess, NULL, WNOHANG); +} + + +void execCommand(char **cmd) { + // Create a child process from current (?) + pid_t varProcess = fork(); + + // if fork successfully created + if (!varProcess) { + // Execute command + execvp(*cmd, cmd); + } + + // Wait for command closing + waitpid(varProcess, NULL, 0); +} + +int GetFileSize(char *file) +{ + struct stat st; + if (stat(file, &st) == 0){ + return st.st_size; + } + return 0; +} + +float GetCpuUsage() +{ + FILE *fp; + char b[32]; + + fp = popen("grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage}'","r"); + + if (fp == NULL) + { + return 0; + } + + if ( fgets(b,sizeof(b)-1, fp) == NULL ) + { + return 0; + } + + pclose(fp); + + return atof(b); +} + +float GetRamUsage() +{ + FILE *fp; + char b[32]; + + fp = popen("free -m | awk \'NR==2{printf \"%.2f\\n\", $3*100/$2 }\'","r"); + + if (fp == NULL) + { + return 0; + } + + if ( fgets(b,sizeof(b)-1, fp) == NULL ) + { + return 0; + } + + pclose(fp); + + return atof(b); +} + +int GetDirSize(char *dir) +{ + DIR *d; + struct dirent *de; + struct stat st; + long long dir_size = 0; + char fn[256]; + + if ((d = opendir(dir)) == NULL ) + { + return 0; + } + + while((de = readdir(d)) != NULL) + { + if (de->d_type == DT_REG) + { + sprintf(fn,"%s/%s",dir,de->d_name); + + if (stat(fn,&st) == -1) + continue; + + dir_size += st.st_size; + } + } + closedir(d); + + // convert to megabytes + return (int)(dir_size>>20); +} + +char *GetOldestFileInDir(char *dir) +{ + DIR *d; + struct dirent *de; + struct stat st; + char fn[256]; + char *res = NULL; + time_t t = 0; + + if ((d = opendir(dir)) == NULL) + { + return NULL; + } + + while((de = readdir(d)) != NULL) + { + if (de->d_type == DT_REG) + { + sprintf(fn,"%s/%s",dir,de->d_name); + + if (stat(fn,&st) == -1) + continue; + + if ((!t) + || (t > st.st_mtime)) + { + t = st.st_mtime; + res = strdup(fn); + } + } + } + closedir(d); + + return res; +} + +int RemoveFiles(char *path) +{ + if ( access(path, F_OK) == -1 ) + { + // file not exists + return -1; + } + + return remove(path); +} + +char *GetIMEI() +{ + FILE *fp; + char b[32] = {0}; + char *path = "/etc/simman/getimei.sh"; + char *defval = "NONE"; + + if (access(path, F_OK) == -1) + // script not found + return NULL; + + fp = popen("cat /tmp/simman/imei","r"); + + if (fp == NULL) + { + return strdup(defval); + } + + if ( fgets(b,sizeof(b)-1, fp) == NULL ) + { + return strdup(defval); + } + pclose(fp); + + *(char*)(b+15) = '\0'; + + if (strstr(b,"NONE") == NULL) + // return current CCID + return strdup(b); + + // need update from GSM + fp = popen(path,"r"); + + if (fp == NULL) + { + return strdup(defval); + } + + if ( fgets(b,sizeof(b)-1, fp) == NULL ) + { + return strdup(defval); + } + + pclose(fp); + + *(char*)(b+15) = '\0'; + + if ((strstr(b,"NONE") == NULL) + && strlen(b)) + { + // update uci configuration + char cmd[128]; + sprintf(cmd,"echo %s > /tmp/simman/imei",b); + //fprintf(stderr,"diag: %s\n", cmd); + + fp = popen(cmd,"r"); + + if (fp != NULL) + pclose(fp); + } + + return strdup(b); + +} + +char *GetCCID() +{ + FILE *fp; + char b[32] = {0}; + char *path = "/etc/simman/getccid.sh"; + char *defval = "NONE"; + uint8_t i; + + if (access(path, F_OK) == -1) + { + // script not found + fprintf(stderr,"diag: script %s not found\n",path); + return strdup(defval); + } + + // need update from GSM + fp = popen(path,"r"); + + if (fp == NULL) + { + return strdup(defval); + } + + if ( fgets(b,sizeof(b)-1, fp) == NULL ) + { + return strdup(defval); + } + pclose(fp); + + for (i =0; i < 20; i++) + { + if (b[i]=='\n') + break; + } + for ( ; i <= 20; i++) + b[i] = '\0'; + + if ((strstr(b,"NONE") == NULL) + && (strlen(b))) + { + // update uci configuration + char cmd[128]; + sprintf(cmd,"echo %s > /tmp/simman/ccid",b); + //fprintf(stderr,"diag: %s\n", cmd); + + fp = popen(cmd,"r"); + + if (fp != NULL) + pclose(fp); + } + + return strdup(b); +} + +int GetSIG() +{ + FILE *fp; + char b[32]; + char path[] = "/etc/simman/getcsq.sh"; + + if ( access(path, F_OK) == -1 ) + return 0; + + fp = popen(path,"r"); + + if (fp == NULL) + { + pclose(fp); + return 0; + } + + if ( fgets(b,sizeof(b)-1, fp) == NULL ) + { + pclose(fp); + return 0; + } + pclose(fp); + + return atoi(b); +} + +char *GetUCIParam(char *uci_path) +{ + char path[128]= {0}; + char buffer[80] = { 0 }; + struct uci_ptr ptr; + struct uci_context *c = uci_alloc_context(); + + if(!c) return NULL; + + strcpy(path, uci_path); + + // fprintf(stderr,"%s\n",path); + + if ((uci_lookup_ptr(c, &ptr, path, true) != UCI_OK) || + (ptr.o==NULL || ptr.o->v.string==NULL)) + { + uci_free_context(c); + return NULL; + } + + if(ptr.flags & UCI_LOOKUP_COMPLETE) + strcpy(buffer, ptr.o->v.string); + + uci_free_context(c); + + return strdup(buffer); +} + +int ping(char *ip, char *iface) +//int ping(char *ip) +{ + FILE *fp; + char b[128]; + char path[128] = {0}; + + if(iface == NULL) + sprintf(path,"/bin/ping -w10 -c2 -s 8 %s | grep 'rec' | awk -F'[ ]' '{print $4}'",ip); + else + sprintf(path,"/bin/ping -w10 -c2 -s 8 -I %s %s | grep 'rec' | awk -F'[ ]' '{print $4}'", iface, ip); + + fp = popen(path,"r"); + + if (fp == NULL) + { + pclose(fp); + return 0; + } + + if ( fgets(b,sizeof(b)-1, fp) == NULL ) + { + pclose(fp); + return 0; + } + + pclose(fp); + + return atoi(b); +} + +int gpioRead(int gpio) +{ + char buf[64]; + int fd, ret; + sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); + + if ((fd = open(buf, O_RDONLY)) < 0) + return -1; + + if ((ret = read(fd, buf, 1)) > 0) + { + if (*buf == '0') ret=0; + else + if (*buf == '1') ret=1; + } + close(fd); + + return ret; +} + +int gpioSet(int gpio, int value) +{ + char buf[64]; + int fd, ret; + sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); + + if ((fd = open(buf, O_WRONLY)) < 0) + return -1; + + sprintf(buf, "%d", value); + ret = write(fd, buf, 1); + close(fd); + + return ret; +} + +char *GetModemInfo(int InfoParam , char *dev) +{ + FILE *fp; + char b[64] = {0}; + char *defval = "error"; + char *path; + char *keypath; + switch(InfoParam) + { + case INFO_SIM: + path = "/etc/simman/getsimcheck.sh"; + break; + case INFO_CCID: + path = "/etc/simman/getccid.sh"; + break; + case INFO_PINSTAT: + path = "/etc/simman/getpinstat.sh"; + break; + case INFO_SIGLEV: + path = "/etc/simman/getsiglev.sh"; + break; + case INFO_REGSTAT: + path = "/etc/simman/getreg.sh"; + break; + case INFO_BASESTID: + path = "/etc/simman/getbasestid.sh"; + break; + case INFO_BASESTBW: + path = "/etc/simman/getband.sh"; + break; + case INFO_NETTYPE: + path = "/etc/simman/getnettype.sh"; + break; + case INFO_GPRSSTAT: + path = "/etc/simman/getgprsreg.sh"; + break; + case INFO_PACKTYPE: + path = "/etc/simman/getpackinfo.sh"; + break; + case INFO_IMEI: + path = "/etc/simman/getimei.sh"; + break; + default: + return strdup(defval); + } + + uint8_t i; + + if (access(path, F_OK) == -1) + { + // script not found + fprintf(stderr,"diag: script %s not found\n",path); + return strdup(defval); + } + + // need update from GSM + keypath = malloc(strlen(path) + strlen(dev) + 5); // should it be free ??? + if (keypath) { + strcpy(keypath, path); + strcat(keypath, " -d "); + strcat(keypath, dev); + } + + fp = popen(keypath,"r"); + + if (fp == NULL) + { + return strdup(defval); + } + + if ( fgets(b,sizeof(b)-1, fp) == NULL ) + { + return strdup(defval); + } + pclose(fp); + + for (i =0; i < 64; i++) + { + if (b[i]=='\n') + break; + } + for ( ; i <= 64; i++) + b[i] = '\0'; + if (/*(strstr(b,"NONE") == NULL) &&*/ ( strlen(b) )) + { + // update uci configuration + char cmd[256]; + switch(InfoParam) + { + case INFO_SIM: + sprintf(cmd,"uci set simman.info.sim=%s && uci commit simman",b); + break; + case INFO_CCID: + sprintf(cmd,"uci set simman.info.ccid=%s && uci commit simman",b); + break; + case INFO_PINSTAT: + sprintf(cmd,"uci set simman.info.pincode_stat=%s && uci commit simman",b); + break; + case INFO_SIGLEV: + sprintf(cmd,"uci set simman.info.sig_lev=%s && uci commit simman",b); + break; + case INFO_REGSTAT: + sprintf(cmd,"uci set simman.info.reg_stat=%s && uci commit simman",b); + break; + case INFO_BASESTID: + sprintf(cmd,"uci set simman.info.base_st_id=%s && uci commit simman",b); + break; + case INFO_BASESTBW: + sprintf(cmd,"uci set simman.info.base_st_bw=%s && uci commit simman",b); + break; + case INFO_NETTYPE: + sprintf(cmd,"uci set simman.info.net_type=%s && uci commit simman",b); + break; + case INFO_GPRSSTAT: + sprintf(cmd,"uci set simman.info.gprs_reg_stat=%s && uci commit simman",b); + break; + case INFO_PACKTYPE: + sprintf(cmd,"uci set simman.info.pack_type=%s && uci commit simman",b); + break; + case INFO_IMEI: + sprintf(cmd,"uci set simman.info.imei=%s && uci commit simman",b); + break; + default: + return strdup(defval); + } + fp = popen(cmd,"r"); + + if (fp != NULL) + pclose(fp); + } + + return strdup(b); +} diff --git a/simman/src/common.h b/simman/src/common.h new file mode 100755 index 00000000..806b0564 --- /dev/null +++ b/simman/src/common.h @@ -0,0 +1,40 @@ +#ifndef _common_h +#define _common_h + +#define INFO_SIM 0 +#define INFO_CCID 1 +#define INFO_PINSTAT 2 +#define INFO_SIGLEV 3 +#define INFO_REGSTAT 4 +#define INFO_BASESTID 5 +#define INFO_BASESTBW 6 +#define INFO_NETTYPE 7 +#define INFO_GPRSSTAT 8 +#define INFO_PACKTYPE 9 +#define INFO_IMEI 10 + + +void execCommandNoWait(char **cmd); +void execCommand(char **cmd); +int GetFileSize(char *file); +float GetCpuUsage(void); +float GetRamUsage(void); +int GetDirSize(char *dir); // return value in Megabytes +char *GetOldestFileInDir(char *dir); +int RemoveFiles(char *path); +char *GetIMEI(void); +char *GetCCID(void); +int GetSIG(void); + +/** +* @brief Read parameter fro UCI +* @param path UCI string +* @return Return string parameter value or null if parameter not exists +*/ +char *GetUCIParam(char *path); +int ping(char *ip, char *iface); +//int ping(char *ip); +int gpioRead(int gpio); +int gpioSet(int gpio, int value); +#endif + diff --git a/simman/src/log.h b/simman/src/log.h new file mode 100755 index 00000000..fa04078d --- /dev/null +++ b/simman/src/log.h @@ -0,0 +1,18 @@ +#ifndef _log_h +#define _log_h + +#include +#include + +#define LOG(fmt, ...) do { \ + syslog(LOG_NOTICE,"simman: "fmt, ## __VA_ARGS__); \ + fprintf(stderr, "simman: "fmt, ## __VA_ARGS__); \ + } while (0) + +#define ERROR(fmt, ...) do { \ + syslog(LOG_ERR,"simman: "fmt, ## __VA_ARGS__); \ + fprintf(stderr, "simman: "fmt, ## __VA_ARGS__); \ + } while (0) + +#endif + diff --git a/simman/src/simman.c b/simman/src/simman.c new file mode 100755 index 00000000..d4b06463 --- /dev/null +++ b/simman/src/simman.c @@ -0,0 +1,813 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SYSLOG_NAMES +#include + +#include "common.h" +#include "log.h" + +#define SETSIM_SCRIPT "/etc/simman/setsim.sh" + +enum { + INIT = 0, + IDLE, + GET_CCID, + GET_IMEI, + CH_SIM, +}; + +typedef struct testip{ + uint8_t *ip; + uint16_t retry_check; + uint8_t sim_num; // 0 - sim0, 1 - sim1, 2 - both +}testip_t; + +typedef struct sim_s +{ + uint8_t init; + uint8_t prio; + uint8_t *pin; + uint8_t *user; + uint8_t *pass; + uint8_t *apn; +}sim_t; + +typedef struct settings_s{ + uint8_t only_first_sim; + uint8_t retry_num; + uint16_t check_period; + uint16_t delay; + uint16_t csq_level; + testip_t serv[8]; + sim_t sim[2]; + uint8_t *atdevice; + uint8_t *iface; + uint16_t sw_before_modres; + uint16_t sw_before_sysres; + uint8_t *imei; + uint8_t *ccid; + uint16_t gsmpow_pin; + uint16_t simdet_pin; + uint16_t simaddr_pin; + uint16_t simdet0_pin; + uint16_t simdet1_pin; +}settings_t; + +typedef struct current_info{ + uint8_t *atdevice; + uint8_t *sim; + uint8_t *imei; // + uint8_t *ccid; // + uint8_t *pincode_stat; + uint8_t *sig_lev; // + uint8_t *reg_stat; + uint8_t *base_st_id; + uint8_t *base_st_bw; + uint8_t *net_type; + uint8_t *gprs_reg_stat; + uint8_t *pack_type; + +}current_info_t; + +static settings_t settings; +static current_info_t siminfo; + +int sim1_status=-1, // SIM1 status, 0 - detect, 1 - not detect, -1 - unknown + sim2_status=-1, // SIM2 status + first_start, + active_sim; // active SIM, 0 - SIM1, 1 - SIM2, -1 - unknown + +int8_t state, + changeCounter, + changeCounterForReboot, + retry; + +int GetSimInfo(char *device) +{ + siminfo.sim = GetModemInfo(INFO_SIM, device); + siminfo.ccid = GetModemInfo(INFO_CCID, device); + siminfo.pincode_stat = GetModemInfo(INFO_PINSTAT, device); + siminfo.sig_lev = GetModemInfo(INFO_SIGLEV, device); + siminfo.reg_stat = GetModemInfo(INFO_REGSTAT, device); + siminfo.base_st_id = GetModemInfo(INFO_BASESTID, device); + siminfo.base_st_bw = GetModemInfo(INFO_BASESTBW, device); + siminfo.net_type = GetModemInfo(INFO_NETTYPE, device); + siminfo.gprs_reg_stat = GetModemInfo(INFO_GPRSSTAT, device); + siminfo.pack_type = GetModemInfo(INFO_PACKTYPE, device); + siminfo.imei = GetModemInfo(INFO_IMEI, device); + return 0; +} + +int ReadConfiguration(settings_t *set) +{ + char * p, path[128]; + char i,j; + + if ((p = GetUCIParam("simman.core.only_first_sim")) == NULL) + { + fprintf(stderr,"Error reading only_first_sim\n"); + return -1; + } + settings.only_first_sim = atoi(p); + + if ((p = GetUCIParam("simman.core.retry_num")) == NULL) + { + fprintf(stderr,"Error reading retry_num\n"); + return -1; + } + settings.retry_num = atoi(p); + + if ((p = GetUCIParam("simman.core.check_period")) == NULL) + { + fprintf(stderr,"Error reading check_period\n"); + return -1; + } + settings.check_period = atoi(p); + + if ((p = GetUCIParam("simman.core.delay")) == NULL) + { + fprintf(stderr,"Error reading delay\n"); + return -1; + } + settings.delay = atoi(p); + + if ((p = GetUCIParam("simman.core.csq_level")) == NULL) + { + settings.csq_level = 0; + } + settings.csq_level = atoi(p); + + if ((p = GetUCIParam("simman.core.sw_before_modres")) == NULL) + { + fprintf(stderr,"Error reading sw_before_modres\n"); + settings.sw_before_modres = 0; + return -1; + } + settings.sw_before_modres = atoi(p); + + if(settings.sw_before_modres > 100) + settings.sw_before_modres = 100; + else if(settings.sw_before_modres < 0) + settings.sw_before_modres = 0; + + if ((p = GetUCIParam("simman.core.sw_before_sysres")) == NULL) + { + fprintf(stderr,"Error reading sw_before_sysres\n"); + settings.sw_before_sysres = 0; + return -1; + } + settings.sw_before_sysres = atoi(p); + if(settings.sw_before_sysres > 100) + settings.sw_before_sysres = 100; + else if(settings.sw_before_sysres < 0) + settings.sw_before_sysres = 0; + + if ((p = GetUCIParam("simman.core.testip")) == NULL) + { + fprintf(stderr,"Error reading testip\n"); + return -1; + } + + char *tok = strtok(p," "); + + for (i = 0; i < sizeof(settings.serv)/sizeof(settings.serv[0]); i++) + { + settings.serv[i].ip = NULL; + settings.serv[i].retry_check = 0; + settings.serv[i].sim_num = NULL; + } + + i = 0; + while(tok && i < sizeof(settings.serv)/sizeof(settings.serv[0])) + { + settings.serv[i].sim_num = 2; + settings.serv[i++].ip = tok; + tok = strtok(NULL," "); + } + j = i; + for (i = 0; i < sizeof(settings.sim)/sizeof(settings.sim[0]); i++) + { + settings.sim[i].init = 0; + + sprintf(path,"simman.@sim%d[0].priority",i); + if ((p = GetUCIParam(path)) == NULL) + { + fprintf(stderr,"Error reading sim[%d].priority\n",i); + continue; + } + settings.sim[i].prio = atoi(p); + sprintf(path,"simman.@sim%d[0].testip",i); + if ((p = GetUCIParam(path)) != NULL) + { + char *tok = strtok(p," "); + while(tok && j < sizeof(settings.serv)/sizeof(settings.serv[0])) + { + settings.serv[j].sim_num = i; + settings.serv[j++].ip = tok; + tok = strtok(NULL," "); + } + } + /* + sprintf(path,"simman.@sim[%d].pin",i); + if ((p = GetUCIParam(path)) == NULL) + { + fprintf(stderr,"Error reading sim[%d].pin\n",i); + continue; + } + settings.sim[i].pin = p; + + sprintf(path,"simman.@sim[%d].GPRS_user",i); + if ((p = GetUCIParam(path)) == NULL) + { + fprintf(stderr,"Error reading sim[%d].user\n",i); + continue; + } + settings.sim[i].user = p; + + sprintf(path,"simman.@sim[%d].GPRS_pass",i); + if ((p = GetUCIParam(path)) == NULL) + { + fprintf(stderr,"Error reading sim[%d].pass\n",i); + continue; + } + settings.sim[i].pass = p; + + sprintf(path,"simman.@sim[%d].GPRS_apn",i); + if ((p = GetUCIParam(path)) == NULL) + { + fprintf(stderr,"Error reading sim[%d].apn\n",i); + continue; + } + settings.sim[i].apn = p; + */ + settings.sim[i].init = 1; + } + + if (!(settings.sim[0].init || settings.sim[1].init)) + { + fprintf(stderr,"No find SIM card info\n"); + return -1; + } + + if ((p = GetUCIParam("simman.core.atdevice")) == NULL) + { + fprintf(stderr,"Error reading atdevice\n"); + return -1; + } + settings.atdevice = p; + + if ((p = GetUCIParam("simman.core.iface")) == NULL) + { + fprintf(stderr,"Error reading interface\n"); + return -1; + } + settings.iface = p; + + if ((p = GetUCIParam("simman.core.gsmpow_gpio_pin")) == NULL) + { + fprintf(stderr,"Error reading gsmpow_gpio_pin\n"); + return -1; + } + settings.gsmpow_pin = atoi(p); + + if ((p = GetUCIParam("simman.core.simdet_gpio_pin")) == NULL) + { + fprintf(stderr,"Error reading simdet_gpio_pin\n"); + return -1; + } + settings.simdet_pin = atoi(p); + + if ((p = GetUCIParam("simman.core.simaddr_gpio_pin")) == NULL) + { + fprintf(stderr,"Error reading simaddr_gpio_pin\n"); + return -1; + } + settings.simaddr_pin = atoi(p); + + if ((p = GetUCIParam("simman.core.simdet0_gpio_pin")) == NULL) + { + fprintf(stderr,"Error reading simdet0_gpio_pin\n"); + return -1; + } + settings.simdet0_pin = atoi(p); + + if ((p = GetUCIParam("simman.core.simdet1_gpio_pin")) == NULL) + { + fprintf(stderr,"Error reading simdet1_gpio_pin\n"); + return -1; + } + settings.simdet1_pin = atoi(p); + + fprintf(stderr,"retry_num=%d, check_period=%d, delay=%d, atdevice=%s, gsmpow_pin=%d, simdet_pin=%d, simaddr_pin=%d, simdet0_pin=%d, simdet1_pin=%d, ", + settings.retry_num, + settings.check_period, + settings.delay, + settings.atdevice, + settings.gsmpow_pin, settings.simdet_pin, settings. simaddr_pin, settings.simdet0_pin, settings.simdet1_pin ); + for (i = 0; i < sizeof(settings.serv)/sizeof(settings.serv[0]);i++) + if (settings.serv[i].ip) + fprintf(stderr,"%s ",settings.serv[i].ip); + + fprintf(stderr,"\n"); + + /* for (i = 0; i < sizeof(settings.sim)/sizeof(settings.sim[0]);i++) + if (settings.sim[i].init) + fprintf(stderr,"sim_%i) -> prio=%d, pin=%s, user=%s, pass=%s, apn=%s\n", + i, + settings.sim[i].prio, + settings.sim[i].pin, + settings.sim[i].user, + settings.sim[i].pass, + settings.sim[i].apn); + */ + return 0; +} + +static int usage(const char *prog) +{ + fprintf(stderr, "Usage: %s\n" + "\n", prog); + exit(0); +} + +int ModemStarted(char *atdevice) +{ + // 0 - OK, -1 - not found + return access(atdevice, F_OK); +} + +int ModemReset() +{ + gpioSet(settings.gsmpow_pin,1); + sleep(5); + gpioSet(settings.gsmpow_pin,0); +} + +int SetSim(uint8_t sim) +{ + changeCounterForReboot++; + changeCounter++; + //LOG("changeCounter now %d and changeCounterForReboot %d \n", changeCounter, changeCounterForReboot); + if ((settings.only_first_sim == 0) || (first_start == 1)) + { + if (access(SETSIM_SCRIPT, 0) != 0) + { + LOG("not found %s\n", SETSIM_SCRIPT); + return -1; + } + + char *cmd[] = {strdup(SETSIM_SCRIPT), + "-s", (sim)?"1":"0", + 0, 0}; + + //LOG("execute %s %s %s\n", cmd[0], + //cmd[1], cmd[2]); + + execCommand(cmd); + first_start = 0; + + } + else + { + LOG("switching to over SIM is not necessary"); + if (access(SETSIM_SCRIPT, 0) != 0) + { + LOG("not found %s\n", SETSIM_SCRIPT); + return -1; + } + + char *cmd[] = {strdup(SETSIM_SCRIPT), + "-s", (!sim)?"1":"0", + 0, 0}; + + //LOG("execute %s %s %s\n", cmd[0], + //cmd[1], cmd[2]); + + execCommand(cmd); + } + + if(settings.sw_before_sysres != 0) + { + if(changeCounterForReboot > settings.sw_before_sysres) + { + LOG("Sim switched %d times\n", changeCounterForReboot); + LOG("Reboot...\n"); + sync(); + reboot(RB_AUTOBOOT); + } + } + + if(settings.sw_before_modres != 0) + { + if(changeCounter > settings.sw_before_modres) + { + LOG("Sim switched %d times\n", changeCounter); + if (access(SETSIM_SCRIPT, 0) != 0) + { + LOG("not found %s\n", SETSIM_SCRIPT); + return -1; + } + + char *cmd1[] = {strdup(SETSIM_SCRIPT), "-p" }; + + LOG("Modem reset...\n"); + execCommand(cmd1); + changeCounter = 0; + changeCounterForReboot--; + first_start = 1; + } + + } + + if(changeCounter>101) + changeCounter=0; + if(changeCounterForReboot>101) + changeCounterForReboot=0; + + return 0; +} + +int main(int argc, char **argv) +{ + int ch, ret = 0; + int i, + tmp, + ch_sim, + num_sim, + sig_level, + hot_change; + + time_t now_time, prev_time, prev_delay_time; + double diff, diff_delay; + + signal(SIGPIPE, SIG_IGN); + + while ((ch = getopt(argc, argv, "h")) != -1) { + switch (ch) { + case 'h': + default: + return usage(*argv); + } + } + + time(&now_time); + prev_time = prev_delay_time = now_time; + + state = -1; + first_start = 1; + hot_change = 1; + ch_sim = 0; + changeCounter = 0; + changeCounterForReboot = 0; + + LOG("service started\n"); + + if ( ReadConfiguration(&settings) == 0 ) + do{ + // get now time + time(&now_time); + // in seconds + diff = difftime(now_time, prev_time); + diff_delay = difftime(now_time, prev_delay_time); + + // check if modem exists + if ( ModemStarted(settings.atdevice) < 0 ) + { + if ((state < 0) || (state != INIT)) + { + LOG("modem not found, try to turn on\n"); + ModemReset(); + sleep(60); + first_start = 1; + // changeCounter = settings.sw_before_modres; + // SetSim(active_sim); + } + state = INIT; + } + else + if (state == INIT) + { + LOG("modem started\n"); + state = GET_IMEI; + } + + // read num active SIM card + active_sim = gpioRead(settings.simaddr_pin); + + // check SIM1 status + tmp = gpioRead(settings.simdet0_pin); + if ((tmp >= 0) && (tmp != sim1_status) && !first_start) + { // SIM1 remove + if (((tmp == 1)&&(active_sim == 0)) // вытянули сим 1 + ||((tmp == 0)&&(settings.sim[0].prio > settings.sim[1].prio)) // вставили сим 1 и приоритет у нее выше + ||((tmp == 0)&&(sim2_status != 0))) // вытащили сим 2 и приоритет у нее выше + { + for (i = 0; i < sizeof(settings.serv)/sizeof(settings.serv[0]); i++) + { + settings.serv[i].retry_check = 0; + } + hot_change = 1; + state = CH_SIM; + } + } + sim1_status = tmp; + + // check SIM2 status + tmp = gpioRead(settings.simdet1_pin); + if ((tmp >= 0) && (tmp != sim2_status) && !first_start) + { // SIM2 remove + if (((tmp == 1)&&(active_sim > 0)) // вытянули сим 2 + ||((tmp == 0)&&(settings.sim[0].prio < settings.sim[1].prio)) // вставили сим 2 и приоритет у нее выше + ||((tmp == 0)&&(sim1_status != 0))) // вытащили сим 1 и приоритет у нее выше + { + for (i = 0; i < sizeof(settings.serv)/sizeof(settings.serv[0]); i++) + { + settings.serv[i].retry_check = 0; + } + hot_change = 1; + state = CH_SIM; + } + } + sim2_status = tmp; + + if (first_start) + { + if (settings.sim[0].prio < settings.sim[1].prio) + { + if (active_sim == 0) + { + if (sim2_status==0) //если SIM2 обнаружена + { + SetSim(1); + LOG("SIM2 has the highest priority\n"); + } + else + { + LOG("SIM2 is not available\n"); + SetSim(0); + } + } + else + { + if (active_sim == 1) + { + if ((sim2_status != 0)&&(sim1_status == 0)) + { + LOG("Only SIM1 detected\n"); + SetSim(0); + } + else + { + LOG("SIM2 is active\n"); + SetSim(active_sim); + } + } + else + LOG("No one SIM is available\n"); + } + } + else + { + if (active_sim == 1) + { + if (sim1_status==0) //Если SIM1 обнаружена + { + SetSim(0); + LOG("SIM1 has the highest priority\n"); + } + else + { + LOG("SIM1 is not available\n"); + SetSim(1); + } + } + else + { + if (active_sim == 0) + { + if ((sim1_status != 0)&&(sim2_status == 0)) + { + LOG("Only SIM2 detected\n"); + SetSim(1); + } + else + { + LOG("SIM1 is active\n"); + SetSim(active_sim); + } + } + else + LOG("No one SIM is available\n"); + } + } + hot_change = 0; + } + first_start = hot_change; + hot_change = 0; + + // Если работаем на карте с низким приоритетом, + // пробуем переключится на карту с высшим приоритетом + if (((active_sim == 0 ) && (settings.sim[0].prio < settings.sim[1].prio)) + ||((active_sim > 0) && (settings.sim[0].prio > settings.sim[1].prio))) + { + if ( diff_delay >= settings.delay ) + { + prev_delay_time = now_time; + ch_sim = 1; + + LOG("attempt to switch to the priority SIM (act.SIM%d p1/p2=%d/%d)\n", + active_sim+1, + settings.sim[0].prio, + settings.sim[1].prio); + } + } + else + { + prev_delay_time = now_time; + } + + + fprintf(stderr,"%.0f %d %d %d\n", diff, sim1_status, sim2_status, active_sim); + + switch(state) + { + case INIT: break; + case GET_IMEI: + // get modem IMEI + if ( (long int)diff >= 3) + { + settings.imei = GetIMEI(); + + prev_time = now_time; + + if (strstr(settings.imei,"NONE") != NULL) + { + if (++retry >= 2 ) + state = IDLE; + else + LOG("retry #%d reading IMEI\n", retry+1); + + break; + } + LOG("found modem with IMEI %s\n",settings.imei); + state = GET_CCID; + } + break; + case GET_CCID: + if ( (long int)diff >= 3) + { + settings.ccid = GetCCID(); + + prev_time = now_time; + + if (strstr(settings.ccid,"NONE") != NULL) + { + if (++retry >= 2 ) + state = IDLE; + else + LOG("retry #%d reading CCID\n", retry+1); + break; + } + LOG("act. SIM%d with CCID %s\n", active_sim+1, settings.ccid); + state = IDLE; + } + break; + case IDLE: + if (ch_sim) + { // if need change SIM card + ch_sim = 0; + state = CH_SIM; + break; + } + + if (diff < settings.check_period && diff >= 0) + break; + + if (settings.csq_level != 0){ + sig_level = GetSIG(); + if (sig_level == 99) { + sleep(1); + sig_level = GetSIG(); + } + LOG("Current ASU: %d\n", sig_level); + if (sig_level < settings.csq_level || sig_level == 99) + LOG("ASU not detectable or below specified: %d ASU (min: %d ASU)\n", sig_level, settings.csq_level); + } + + LOG("check servers\n"); + + uint8_t need_change_sim = 0; + + for (i = 0; i < sizeof(settings.serv)/sizeof(settings.serv[0]); i++) + { + if (!settings.serv[i].ip) + break; + if (settings.serv[i].sim_num == 2 || settings.serv[i].sim_num == active_sim) { + int ack, cnt = 0; + do{ + ack = ping((char*)settings.serv[i].ip, (char*)settings.iface); + //ack = ping((char*)settings.serv[i].ip); + }while(!ack && (++cnt < 3)); + + if (!ack) + settings.serv[i].retry_check++; + else if (settings.csq_level != 0 && (sig_level < settings.csq_level || sig_level == 99)) + settings.serv[i].retry_check++; + else + { + settings.serv[i].retry_check = 0; + changeCounter = 0; + changeCounterForReboot = 0; + } + + if (settings.serv[i].retry_check >= settings.retry_num) + need_change_sim++; + + if (ack) + { + if (settings.csq_level != 0 && (sig_level < settings.csq_level || sig_level == 99)) + LOG("%s - LIVE; ASU LOW (%d/%d)\n", settings.serv[i].ip,settings.serv[i].retry_check, settings.retry_num); + else + LOG("%s - LIVE\n", settings.serv[i].ip); + } + else + LOG("%s - DOWN (%d/%d)\n", settings.serv[i].ip,settings.serv[i].retry_check, settings.retry_num); + } + else + need_change_sim++; + } + + prev_time = now_time; + /*LOG("Reading SIM info..."); + if(GetSimInfo(settings.atdevice)) + LOG("Error while reading SIM info\n"); + LOG("OK\n");*/ + // change sim if all servers id down + if (i == need_change_sim) + { + ch_sim = 1; + + // clear + for (i = 0; i < sizeof(settings.serv)/sizeof(settings.serv[0]); i++) + { + if (!settings.serv[i].ip) + break; + + settings.serv[i].retry_check = 0; + } + } + break; + case CH_SIM: + // need change SIM card + if (active_sim >= 0) + { + num_sim = active_sim; + if (active_sim == 0) + { + if (sim2_status == 0) + { + num_sim = 1; + LOG("attempt to switch to SIM%d\n", num_sim+1); + } + } + else + { + if (sim1_status == 0) + { + num_sim = 0; + LOG("attempt to switch to SIM%d\n", num_sim+1); + } + } + + SetSim(num_sim); + } + + prev_time = now_time; + retry = 0; + + state = GET_CCID; + break; + default: + state = INIT; + break; + } + // ~0.3 sec + usleep(300000); + }while(1); + + LOG("service stopped\n"); + + return 0; +} + diff --git a/simman/src/simman_getinfo.c b/simman/src/simman_getinfo.c new file mode 100755 index 00000000..833349db --- /dev/null +++ b/simman/src/simman_getinfo.c @@ -0,0 +1,104 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "log.h" + + +typedef struct current_info{ + uint8_t *atdevice; + uint8_t *sim; + uint8_t *imei; // + uint8_t *ccid; // + uint8_t *pincode_stat; + uint8_t *sig_lev; // + uint8_t *reg_stat; + uint8_t *base_st_id; + uint8_t *base_st_bw; + uint8_t *net_type; + uint8_t *gprs_reg_stat; + uint8_t *pack_type; +}current_info_t; + +current_info_t siminfo; + +int ReadConfiguration(current_info_t *set) +{ + char * p; + if ((p = GetUCIParam("simman.info.atdevice")) == NULL) + { + fprintf(stderr,"Error reading atdevice\n"); + return -1; + } + siminfo.atdevice = p; + return 0; +} + +int ModemStarted(char *atdevice) +{ + // 0 - OK, -1 - not found + return access(atdevice, F_OK); +} + +int GetSimInfo(char *device) +{ + LOG("Looking for SIM \n"); + siminfo.sim = GetModemInfo(INFO_SIM, device); + LOG("%s \n",siminfo.sim); + LOG("Reading SIM CCID\n"); + siminfo.ccid = GetModemInfo(INFO_CCID, device); + LOG("%s \n",siminfo.ccid); + LOG("Reading PIN Status\n"); + siminfo.pincode_stat = GetModemInfo(INFO_PINSTAT, device); + LOG("%s \n",siminfo.pincode_stat); + LOG("Reading Signal Strength\n"); + siminfo.sig_lev = GetModemInfo(INFO_SIGLEV, device); + LOG("%s \n",siminfo.sig_lev); + LOG("Reading Registration Status\n"); + siminfo.reg_stat = GetModemInfo(INFO_REGSTAT, device); + LOG("%s \n",siminfo.reg_stat); + LOG("Reading Base Station ID\n"); + siminfo.base_st_id = GetModemInfo(INFO_BASESTID, device); + LOG("%s \n",siminfo.base_st_id); + LOG("Reading Band\n"); + siminfo.base_st_bw = GetModemInfo(INFO_BASESTBW, device); + LOG("%s \n",siminfo.base_st_bw); + LOG("Reading Network Type\n"); + siminfo.net_type = GetModemInfo(INFO_NETTYPE, device); + LOG("%s \n",siminfo.net_type); + LOG("Reading GPRS Status\n"); + siminfo.gprs_reg_stat = GetModemInfo(INFO_GPRSSTAT, device); + LOG("%s \n",siminfo.gprs_reg_stat); + LOG("Reading Package Type\n"); + siminfo.pack_type = GetModemInfo(INFO_PACKTYPE, device); + LOG("%s \n",siminfo.pack_type); + LOG("Reading Modem IMEI\n"); + siminfo.imei = GetModemInfo(INFO_IMEI, device); + LOG("%s \n",siminfo.imei); + return 0; +} + +int main(int argc, char **argv) +{ + if ( ReadConfiguration(&siminfo) == 0 ) + { + if ( ModemStarted(siminfo.atdevice) < 0 ) + { + LOG("modem not found\n"); + return 1; + } + LOG("Reading SIM info...\n"); + if(GetSimInfo(siminfo.atdevice)) + LOG("Error while reading SIM info\n"); + LOG("OK\n"); + } + return 0; +} diff --git a/simman2/Makefile b/simman2/Makefile new file mode 100755 index 00000000..e8411f3b --- /dev/null +++ b/simman2/Makefile @@ -0,0 +1,55 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=simman2 +PKG_VERSION:=3 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/simman2 +#CMAKE_INSTALL:=1 + +PKG_MAINTAINER:=Konstantin Sklyarec Vladimir Ovseychuk + +include $(INCLUDE_DIR)/package.mk +#include $(INCLUDE_DIR)/cmake.mk + +define Package/simman2 + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Manager for SIM card in 3g modem + DEPENDS:=+libuci +endef + +TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include +TARGET_LDFLAGS += -L$(STAGING_DIR)/usr/lib + +define Package/simman2/description + This package contains utility for sim check manage. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) ./src/* $(PKG_BUILD_DIR)/ +endef + +define Package/simman2/install + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/simman2.defaults $(1)/etc/uci-defaults/10_simman2 + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/simman2 $(1)/sbin/ + $(INSTALL_BIN) $(PKG_BUILD_DIR)/simman2_cli $(1)/sbin/ + $(INSTALL_DIR) $(1)//usr/libexec/rpcd + $(INSTALL_BIN) ./files/simman2.rpcd $(1)/usr/libexec/rpcd/simman2 + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/simman2.config $(1)/etc/config/simman2 + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/simman2.init $(1)/etc/init.d/simman2 + $(INSTALL_DIR) $(1)/etc/simman2 + $(INSTALL_BIN) ./files/nbinfo.sh $(1)/etc/simman2/nbinfo.sh + $(INSTALL_BIN) ./files/setsim.sh $(1)/etc/simman2/setsim.sh + $(INSTALL_BIN) ./files/modeminit $(1)/etc/simman2/modeminit + $(INSTALL_BIN) ./files/nbmodeminit $(1)/etc/simman2/nbmodeminit + $(INSTALL_BIN) ./files/check_prio.sh $(1)/etc/simman2/check_prio.sh + $(CP) ./files/*.gcom $(1)/etc/simman2 +endef + +$(eval $(call BuildPackage,simman2)) diff --git a/simman2/files/check_prio.sh b/simman2/files/check_prio.sh new file mode 100755 index 00000000..c96adca2 --- /dev/null +++ b/simman2/files/check_prio.sh @@ -0,0 +1,176 @@ +#!/bin/sh + +EPMTY_SIM=$(/etc/simman/getsimcheck.sh | grep "NOT INSERTED") +if [[ -n "$EPMTY_SIM" ]]; then + echo "One or both SIM cards are not inserted" + exit 1 +fi + +/etc/init.d/simman stop &>/dev/null + +TESTIP0=$(uci -q get simman.core.testip && uci -q get simman.@sim0[0].testip) +TESTIP1=$(uci -q get simman.core.testip && uci -q get simman.@sim1[0].testip) +ATPORT=$(uci -q get simman.core.atdevice) +IFNAME=$(uci -q get simman.core.iface) + +LOG_PATH=$3 +if [[ -z "$LOG_PATH" ]]; then + LOG_PATH=/tmp/sim_prio_log +fi + +PING0=0 +PING1=0 + +ASU=0 +ASU0=0 +ASU1=0 +NET0=2 +NET1=2 + +ASU2G=$(echo $1 | grep "2G" | awk -F':' '{print $2}') +if [[ -z "$ASU2G" ]]; then + ASU2G=0 +fi +ASU3G=$(echo $2 | grep "3G" | awk -F':' '{print $2}') +if [[ -z "$ASU3G" ]]; then + ASU3G=0 +fi + +#echo $ASU2G:$ASU3G + +UP_COUNT=0 +DOWN_COUNT=0 + +set_high(){ + if [[ "$1" -eq "0" ]]; then + uci set simman.@sim0[0].priority='1' + uci set simman.@sim1[0].priority='0' + echo "$(date): set high SIM0" >> $LOG_PATH + elif [[ "$1" -eq "1" ]]; then + uci set simman.@sim0[0].priority='0' + uci set simman.@sim1[0].priority='1' + echo "$(date): set high SIM1" >> $LOG_PATH + fi +} + +/etc/simman/setsim.sh -s0 +sleep 60 + +for IP in $TESTIP0 +do + COUNT=0 + while [[ "$COUNT" -le "2" ]]; do + ping -w5 -c1 -s8 -I $IFNAME $IP &> /dev/null + if [[ "$?" -eq "0" ]]; then + let UP_COUNT++ + PING0=1 + else + let DOWN_COUNT++ + fi + ASU=$(gcom -d $ATPORT -s /etc/simman/getsiglev.gcom | awk -F',' '{print $1}') + if [[ "$ASU" -eq "99" ]]; then + ASU=0 + fi + if [[ "$ASU" -gt "$ASU0" ]]; then + ASU0=$ASU + fi + #echo $ASU0 + sleep 2 + let COUNT++ + done +done + +#echo "UP:$UP_COUNT;DOWN:$DOWN_COUNT" +#echo ASU0$ASU0 + +NET=$(/etc/simman/getnettype.sh) +if [[ "$NET" == "3G" ]]; then + NET0=3 +fi +#echo NET:$NET + +UP_COUNT=0 +DOWN_COUNT=0 +ASU=0 +NET=0 + +/etc/simman/setsim.sh -s1 +sleep 60 + +for IP in $TESTIP1 +do + COUNT=0 + while [[ "$COUNT" -le "2" ]]; do + ping -w5 -c1 -s8 -I $IFNAME $IP &> /dev/null + if [[ "$?" -eq "0" ]]; then + let UP_COUNT++ + PING1=1 + else + let DOWN_COUNT++ + fi + ASU=$(gcom -d $ATPORT -s /etc/simman/getsiglev.gcom | awk -F',' '{print $1}') + if [[ "$ASU" -eq "99" ]]; then + ASU=0 + fi + if [[ "$ASU" -gt "$ASU1" ]]; then + ASU1=$ASU + fi + #echo $ASU1 + sleep 2 + let COUNT++ + done +done + +#echo "UP:$UP_COUNT;DOWN:$DOWN_COUNT" +#echo ASU1$ASU1 + +NET=$(/etc/simman/getnettype.sh) +if [[ "$NET" == "3G" ]]; then + NET1=3 +fi +#echo NET:$NET + +echo "$(date): SIM0: ping=$PING0 NET:$NET0 $ASU0 ASU; SIM1: ping=$PING1 NET:$NET1 $ASU1 ASU" >> $LOG_PATH + +if [[ "$PING0" -eq "0" ]]; then + if [[ "$PING1" -eq "0" ]]; then + echo "Ping is not available on both SIM cards" + if [[ "$NET0" -gt "$NET1" ]]; then + set_high 0 + elif [[ "$NET0" -lt "$NET1" ]]; then + set_high 1 + elif [[ "$ASU0" -gt "$ASU1" ]]; then + set_high 0 + elif [[ "$ASU0" -lt "$ASU1" ]]; then + set_high 1 + fi + else + set_high 1 + fi +else + if [[ "$PING1" -eq "0" ]]; then + set_high 0 + else + if [[ "$NET0" -gt "$NET1" ]]; then + if [[ "$ASU0" -ge "$ASU3G" ]]; then + set_high 0 + elif [[ "$ASU1" -ge "$ASU2G" ]]; then + set_high 1 + fi + elif [[ "$NET0" -lt "$NET1" ]]; then + if [[ "$ASU1" -ge "$ASU3G" ]]; then + set_high 1 + elif [[ "$ASU0" -ge "$ASU2G" ]]; then + set_high 0 + fi + elif [[ "$ASU0" -gt "$ASU1" ]]; then + set_high 0 + elif [[ "$ASU0" -lt "$ASU1" ]]; then + set_high 1 + fi + fi +fi + +/etc/init.d/simman start &>/dev/null + +exit 0 diff --git a/simman2/files/getccidnb.gcom b/simman2/files/getccidnb.gcom new file mode 100755 index 00000000..7030e5e0 --- /dev/null +++ b/simman2/files/getccidnb.gcom @@ -0,0 +1,19 @@ +opengt + set com 9600n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + send "AT+NCCID^m" + waitfor 1 "+NCCID:" + if % = -1 goto error + if % = 0 goto continue + +:error + exit 1 + +:continue + get 1 "^m" $s + print $s + exit 0 diff --git a/simman2/files/getimeinb.gcom b/simman2/files/getimeinb.gcom new file mode 100644 index 00000000..e63a5fb2 --- /dev/null +++ b/simman2/files/getimeinb.gcom @@ -0,0 +1,19 @@ +opengt + set com 9600n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + send "AT+CGSN=1^m" + waitfor 1 "+CGSN:" + if % = -1 goto error + if % = 0 goto continue + +:error + exit 1 + +:continue + get 1 "^m" $s + print $s + exit 0 diff --git a/simman2/files/gpsdata.gcom b/simman2/files/gpsdata.gcom new file mode 100644 index 00000000..478594b5 --- /dev/null +++ b/simman2/files/gpsdata.gcom @@ -0,0 +1,19 @@ +opengt + set com 9600n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + waitfor 5 "$G" + if % = -1 goto timeout + if % = 0 goto continue + +:timeout + print "ERROR" + exit 1 + +:continue + get 1 "^m" $s + print $s + exit 0 diff --git a/simman2/files/gpson.gcom b/simman2/files/gpson.gcom new file mode 100755 index 00000000..e8df67ef --- /dev/null +++ b/simman2/files/gpson.gcom @@ -0,0 +1,15 @@ +opengt + set com 115200n81 + set comecho off + set senddelay 0.02 + waitquiet 0.2 0.2 + flash 0.1 + +:start + send "AT+CGPS=1^m" + waitfor 2 "OK" + send "AT+CGPSAUTO=1^m" + waitfor 2 "OK" + +:continue + exit 0 diff --git a/simman2/files/modeminit b/simman2/files/modeminit new file mode 100644 index 00000000..422f70fb --- /dev/null +++ b/simman2/files/modeminit @@ -0,0 +1,69 @@ +#!/bin/sh + +ATDEVICE=$1 + +SIM7600="SIMCOM SIM7600E-H" +SIM7100="SIMCOM SIM7100E" +SIM5360="SIMCOM SIM5360E" +EHS5="Cinterion EHS5-E" +SIM5300="SIMCOM SIM5300E" +A7602="SIMCOM A7602E-H" + +while [[ ! -e $ATDEVICE ]]; do + sleep 1 +done + +MODEM=$(simman2_cli -d "$ATDEVICE" -m) +while [ -z "$MODEM" ]; do + sleep 1 + MODEM=$(simman2_cli -d "$ATDEVICE" -m) +done + +case "$MODEM" in + "$SIM7100" | "$SIM7600" | "$SIM5360" ) + uci set network.internet="interface" + uci set network.internet.proto="qmi" + uci set network.internet.device="/dev/cdc-wdm0" + uci set network.internet.pdptype="ipv4" + uci set network.internet.autoconnect="0" + uci set network.internet.metric='5' + uci add_list firewall.@zone[1].network='internet' + uci set system.@led[1].dev="wwan0" + uci set system.@led[2].dev="wwan0" + uci commit + ubus call network reload + echo wwan0 > /sys/class/leds/middle\:net/device_name + echo wwan0 > /sys/class/leds/bottom\:act/device_name + exit 0 + ;; + "$EHS5" | "$SIM5300" ) + uci set network.internet="interface" + uci set network.internet.proto="3g" + uci set network.internet.device="/dev/ttyACM0" + uci set network.internet.metric='5' + uci add_list firewall.@zone[1].network='internet' + uci set system.@led[1].dev="3g-internet" + uci set system.@led[2].dev="3g-internet" + uci commit + ubus call network reload + echo 3g-internet > /sys/class/leds/middle\:net/device_name + echo 3g-internet > /sys/class/leds/bottom\:act/device_name + exit 0 + ;; + "$A7602" ) + uci set network.internet="interface" + uci set network.internet.proto="dhcp" + uci set network.internet.device="mobile" + uci set network.internet.metric='5' + uci add_list firewall.@zone[1].network='internet' + uci set system.@led[1].dev="mobile" + uci set system.@led[2].dev="mobile" + uci commit + ubus call network reload + echo mobile > /sys/class/leds/middle\:net/device_name + echo mobile > /sys/class/leds/bottom\:act/device_name + exit 0 + ;; +esac + +exit 0 \ No newline at end of file diff --git a/simman2/files/nbinfo.sh b/simman2/files/nbinfo.sh new file mode 100755 index 00000000..b1938ab6 --- /dev/null +++ b/simman2/files/nbinfo.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +DEVICE="/dev/ttyAMA0" + +send_at(){ + IMEI="$(gcom -d $DEVICE -s /etc/simman/sendat.gcom)" + if [[ "$?" != "0" ]]; then + echo "Not available" + exit 1 + fi +} + +imei(){ + IMEI="$(gcom -d $DEVICE -s /etc/simman/getimeinb.gcom)" + if [[ "$?" != "0" ]]; then + echo "Not available" + exit 1 + fi + echo $IMEI +} + +setfun(){ + FUN=$(COMMAND="?" gcom -d /dev/ttyAMA0 -s /etc/simman/setfunnb.gcom) + if [[ "$FUN" == "0" ]]; then + FUN=$(COMMAND="=1" gcom -d /dev/ttyAMA0 -s /etc/simman/setfunnb.gcom) + sleep 1 + else + FUN=$(COMMAND="=0" gcom -d /dev/ttyAMA0 -s /etc/simman/setfunnb.gcom) + FUN=$(COMMAND="=1" gcom -d /dev/ttyAMA0 -s /etc/simman/setfunnb.gcom) + sleep 1 + fi +} + +ccid(){ + CCID="$(gcom -d $DEVICE -s /etc/simman/getccidnb.gcom)" + if [[ "$?" != "0" ]]; then + echo "Not available" + exit 1 + fi + echo $CCID +} + +imsi(){ + CCID="$(gcom -d $DEVICE -s /etc/simman/getccidnb.gcom)" + if [[ "$?" != "0" ]]; then + echo "Not available" + exit 1 + fi + echo $CCID +} + +case "$1" in + imei) + eval send_at + eval imei + exit 0 + ;; + ccid) + eval send_at + eval setfun + eval ccid + exit 0 + ;; + imsi) + eval send_at + eval setfun + eval imsi + exit 0 + ;; + *) + logger -st nbinfo "Command is not supported. Use the following commands: imei ccid imsi" + exit 0 + ;; +esac diff --git a/simman2/files/nbmodeminit b/simman2/files/nbmodeminit new file mode 100644 index 00000000..4bdb20f6 --- /dev/null +++ b/simman2/files/nbmodeminit @@ -0,0 +1,41 @@ +#!/bin/sh + +. /usr/share/libubox/jshn.sh +json_load "$(ubus call system board)" +json_get_var MODEL model +case "$MODEL" in + "TELEOFIS RTUx68" | "TELEOFIS RTUx68 RE-DE") + ATDEVICE=/dev/ttyAMA0 + + while [[ ! -e $ATDEVICE ]]; do + sleep 1 + done + + MODEM=$(gcom -d "$ATDEVICE" -s /etc/gcom/getcardinfo.gcom) + + if echo "$MODEM" | grep -q SIM7020E; then + uci set network.nbiot=interface + uci set network.nbiot.proto='nbiot' + uci set network.nbiot.delegate='0' + uci set network.nbiot.device=$ATDEVICE + uci set network.nbiot.metric='10' + uci commit network + uci set pingcontrol.nbiot=pingcontrol + uci set pingcontrol.nbiot.enabled='1' + uci set pingcontrol.nbiot.testip='8.8.8.8' + uci set pingcontrol.nbiot.sw_before_modres='3' + uci set pingcontrol.nbiot.sw_before_sysres='0' + uci set pingcontrol.nbiot.check_period='60' + uci set pingcontrol.nbiot.iface='nbiot' + uci commit pingcontrol + NET=$(uci get firewall.@zone[1].network) + NET="${NET} nbiot" + uci set firewall.@zone[1].network="${NET}" + uci commit firewall + ubus call network reload + /etc/init.d/pingcontrol reload + fi + ;; +esac + +exit 0 \ No newline at end of file diff --git a/simman2/files/runcommand.gcom b/simman2/files/runcommand.gcom new file mode 100644 index 00000000..e99b6f92 --- /dev/null +++ b/simman2/files/runcommand.gcom @@ -0,0 +1,31 @@ +# run AT-command from environment +opengt + set com 115200n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + print "sending -> ",$env("COMMAND"),"\n" + send $env("COMMAND") + send "^m" + + waitfor 15 "OK","ERR","ERROR","COMMAND NOT SUPPORT" + if % = 0 goto continue + if % = 1 goto error + if % = 2 goto error + if % = 3 goto notsupported + + print "Timeout running AT-command\n" + exit 1 + +:error + print "Error running AT-command\n" + exit 1 + +:notsupported + print "AT-command not supported\n" + exit 1 + +:continue + exit 0 diff --git a/simman2/files/setfunnb.gcom b/simman2/files/setfunnb.gcom new file mode 100755 index 00000000..fe7f79a1 --- /dev/null +++ b/simman2/files/setfunnb.gcom @@ -0,0 +1,21 @@ +opengt + set com 9600n81 + set senddelay 0.02 + waitquiet 1 0.2 + flash 0.1 + +:start + send "AT+CFUN" + send $env("COMMAND") + send "^m" + waitfor 3 "OK","+CFUN:" + if % = 0 goto continue + if % = 1 goto request + +:request + get 1 "^m" $s + print $s + exit 0 + +:continue + exit 0 diff --git a/simman2/files/setsim.sh b/simman2/files/setsim.sh new file mode 100755 index 00000000..29c796fd --- /dev/null +++ b/simman2/files/setsim.sh @@ -0,0 +1,296 @@ +#!/bin/sh + +OPTIND=1 + +GPIO_PATH=/sys/class/gpio +CONFIG_DIR=/etc/simman +tag=simman + +sim="" +mode="" +pow="" + +while getopts "h?s:mp" opt; do + case "$opt" in + h|\?) + echo "Usage: ./setsim.sh [option]" + echo "Options:" + echo " -s - number sim card, 0 - SIM1 1 - SIM2" + echo " -m - without SIMDET_PIN pushed" + echo " -p - modem power down" + echo "Example: ./setsim.sh -s 1" + exit 0 + ;; + s) sim=$OPTARG + ;; + m) mode="1" + ;; + p) pow="1" + ;; + esac +done + +shift $((OPTIND-1)) +[ "$1" = "--" ] && shift + +[ -z "$sim" ] && { + sim="0" +} + +[ -z "$mode" ] && { + mode="0" +} + +[ -z "$pow" ] && { + pow="0" +} + +# read GPIO configuration +PWRKEY_PIN=$(uci -q get simman2.core.pwrkey_gpio_pin) +[ -z "$PWRKEY_PIN" ] && { + logger -t $tag "Not set PWRKEY_PIN" && exit 0 +} + +GSMPOW_PIN=$(uci -q get simman2.core.gsmpow_gpio_pin) +[ -z "$GSMPOW_PIN" ] && { + logger -t $tag "Not set GSMPOW_PIN" && exit 0 +} + +SIMDET_PIN=$(uci -q get simman2.core.simdet_gpio_pin) +[ -z "$SIMDET_PIN" ] && { + logger -t $tag "Not set SIMDET_PIN" && exit 0 +} + +SIMADDR_PIN=$(uci -q get simman2.core.simaddr_gpio_pin) +[ -z "$SIMADDR_PIN" ] && { + logger -t $tag "Not set SIMADDR_PIN" && exit 0 +} + +SIMDET0_PIN=$(uci -q get simman2.core.simdet0_gpio_pin) +[ -z "$SIMDET0_PIN" ] && { + logger -t $tag "Not set SIMDET0_PIN" && exit 0 +} + +SIMDET1_PIN=$(uci -q get simman2.core.simdet1_gpio_pin) +[ -z "$SIMDET1_PIN" ] && { + logger -t $tag "Not set SIMDET1_PIN" && exit 0 +} + +ATDEVICE=$(uci -q get simman2.core.atdevice) +[ -z "$ATDEVICE" ] && { + logger -t $tag "Not set ATDEVICE" && exit 0 +} + +GPSPORT=$(uci -q get simman2.core.gpsdevice) + +# GPIO ports configure +if [ ! -d "$GPIO_PATH/gpio$GSMPOW_PIN" ]; then + echo $GSMPOW_PIN > $GPIO_PATH/export + echo out > $GPIO_PATH/gpio$GSMPOW_PIN/direction + logger -t $tag "Exporting gpio$GSMPOW_PIN" +fi + +if [ ! -d "$GPIO_PATH/gpio$SIMDET_PIN" ]; then + echo $SIMDET_PIN > $GPIO_PATH/export + echo out > $GPIO_PATH/gpio$SIMDET_PIN/direction + logger -t $tag "Exporting gpio$SIMDET_PIN" +fi + +if [ ! -d "$GPIO_PATH/gpio$SIMADDR_PIN" ]; then + echo $SIMADDR_PIN > $GPIO_PATH/export + echo out > $GPIO_PATH/gpio$SIMADDR_PIN/direction + logger -t $tag "Exporting gpio$SIMADDR_PIN" +fi + +if [ ! -d "$GPIO_PATH/gpio$SIMDET0_PIN" ]; then + echo $SIMDET0_PIN > $GPIO_PATH/export + echo in > $GPIO_PATH/gpio$SIMDET0_PIN/direction + logger -t $tag "Exporting gpio$SIMDET0_PIN" +fi + +if [ ! -d "$GPIO_PATH/gpio$SIMDET1_PIN" ]; then + echo $SIMDET1_PIN > $GPIO_PATH/export + echo in > $GPIO_PATH/gpio$SIMDET1_PIN/direction + logger -t $tag "Exporting gpio$SIMDET1_PIN" +fi + +# find 3g interface +iface="internet" + +[ -z "$iface" ] && logger -t $tag "Not found 3g/4g interface" && exit 0 + +# Check if SIM card placed in holder +sim1=$(cat $GPIO_PATH/gpio$SIMDET0_PIN/value) +sim2=$(cat $GPIO_PATH/gpio$SIMDET1_PIN/value) +ac_sim=$(cat $GPIO_PATH/gpio$SIMADDR_PIN/value) + +if [ "$sim1" == "1" ] && [ "$sim2" == "1" ]; then + logger -t $tag "Both SIM cards are not inserted" + # release SIM_DET pin + echo "0" > $GPIO_PATH/gpio$SIMDET_PIN/value + ubus call network.interface.$iface down + exit 0 +fi + +if [ "$pow" != "1" ]; then +[ "$sim" == "0" ] && { + [ "$sim1" == "1" ] && logger -t $tag "Not inserted sim 1" && exit 0 + [ "$ac_sim" == "0" ] && ubus call network.interface.$iface down && logger -t $tag "SIM 1 is already active" && ubus call network.interface.$iface up && exit 0 + logger -t $tag "Set SIM card 1" +} + +[ "$sim" == "1" ] && { + [ "$sim2" == "1" ] && logger -t $tag "Not inserted sim 2" && exit 0 + [ "$ac_sim" == "1" ] && ubus call network.interface.$iface down && logger -t $tag "SIM 2 is already active" && ubus call network.interface.$iface up && exit 0 + logger -t $tag "Set SIM card 2" +} +else + [ "$sim" == "0" ] && [ "$sim1" == "1" ] && sim="1" + [ "$sim" == "1" ] && [ "$sim2" == "1" ] && sim="0" +fi + +# set down 3g interface +ubus call network.interface.$iface down + +# setting new apn, GPRS settings (pincode, user name, password) +apn=$(uci -q get simman.@sim$sim[0].GPRS_apn) +if [ -z "$apn" ]; then + uci -q delete network.$iface.apn +else + uci -q set network.$iface.apn=$apn +fi + +pin=$(uci -q get simman.@sim$sim[0].pin) +if [ -z "$pin" ]; then + uci -q delete network.$iface.pincode +else + uci -q set network.$iface.pincode=$pin +fi + +user=$(uci -q get simman.@sim$sim[0].GPRS_user) +if [ -z "$user" ]; then + uci -q delete network.$iface.username +else + uci -q set network.$iface.username=$user +fi + +pass=$(uci -q get simman.@sim$sim[0].GPRS_pass) +if [ -z "$pass" ]; then + uci -q delete network.$iface.password +else + uci -q set network.$iface.password=$pass +fi + +/etc/init.d/smstools3 stop &> /dev/null & + +sleep 1 + +# at+cfun=0 for SIM5300 +if [ "$proto" == "3" -a "$pow" -ne "1" ]; then + $CONFIG_DIR/setfun.sh -f 0 +fi + +# power down for SIM5360 +if [ "$proto" == "2" -a "$pow" -ne "1" ]; then + dev=$(ls $ATDEVICE 2>/dev/null) + if [ -n "$dev" ]; then + logger -t $tag "power down for SIM5360" + /etc/init.d/smstools3 stop > /dev/null & + echo "0" > $GPIO_PATH/gpio$PWRKEY_PIN/value + sleep 1 + echo "1" > $GPIO_PATH/gpio$PWRKEY_PIN/value + sleep 3 + dev=$(ls $ATDEVICE 2>/dev/null) + while [ ! -z "$dev" ]; do + sleep 4 + dev=$(ls $ATDEVICE 2>/dev/null) + done + fi +fi + +# Set sim card +if [ "$mode" == "0" ]; then + echo "0" > $GPIO_PATH/gpio$SIMDET_PIN/value + + sleep 1 + + # Power switch + if [ "$pow" == "1" ]; then + logger -t $tag "Reset pin toggle" + if [ -n "$GPSPORT" -a "$GPSPORT" != "/dev/ttyAPP1" ]; then + /etc/init.d/gpsd stop + /etc/init.d/ntpd stop + fi + + # release SIMADDR + echo "0" > $GPIO_PATH/gpio$SIMADDR_PIN/value + + sleep 2 + # power down + echo "1" > $GPIO_PATH/gpio$GSMPOW_PIN/value + + sleep 2 + # power up + echo "0" > $GPIO_PATH/gpio$GSMPOW_PIN/value + + sleep 4 + dev=$(ls $ATDEVICE 2>/dev/null) + while [ -z "$dev" ]; do + sleep 4 + dev=$(ls $ATDEVICE 2>/dev/null) + done + sim="0" + fi +fi + +if [ "$sim" == "1" ]; then + echo "1" > $GPIO_PATH/gpio$SIMADDR_PIN/value +else + echo "0" > $GPIO_PATH/gpio$SIMADDR_PIN/value +fi + +sleep 1 + +if [ "$mode" == "0" ]; then + echo "1" > $GPIO_PATH/gpio$SIMDET_PIN/value +fi + +# at+cfun=1 for SIM5300 +if [ "$proto" == "3" -a "$pow" -ne "1" ]; then + $CONFIG_DIR/setfun.sh -f 1 +fi +# power up for SIM5360 +if [ "$proto" == "2" -a "$pow" -ne "1" ]; then + logger -t $tag "power up for SIM5360" + counter=0 + echo "0" > $GPIO_PATH/gpio$PWRKEY_PIN/value + usleep 50000 + echo "1" > $GPIO_PATH/gpio$PWRKEY_PIN/value + sleep 3 + dev=$(ls $ATDEVICE 2>/dev/null) + while [ -z "$dev" ]; do + sleep 2 + dev=$(ls $ATDEVICE 2>/dev/null) + counter=$(($counter + 1)) + if [ "$counter" == "15" ]; then + echo "0" > $GPIO_PATH/gpio$PWRKEY_PIN/value + usleep 50000 + echo "1" > $GPIO_PATH/gpio$PWRKEY_PIN/value + counter=0 + fi + done + logger -t $tag "SIM5360 powered up" +fi + +sleep 10 && /etc/init.d/smstools3 restart &> /dev/null & + +# store uci changes +uci commit + +# network reload +ubus call network reload + +# reload +ubus call network.interface.$iface up + +exit 0 diff --git a/simman2/files/simman2.config b/simman2/files/simman2.config new file mode 100755 index 00000000..b248689f --- /dev/null +++ b/simman2/files/simman2.config @@ -0,0 +1,34 @@ +config simman2 core + option enabled '1' + option only_first_sim '0' + option retry_num '3' + option check_period '60' + option delay '6000' + list testip '8.8.8.8' + list testip '8.8.4.4' + option atdevice '/dev/ttyGSM1' + option gpsdevice '' + option iface 'internet' + option sw_before_modres '3' + option sw_before_sysres '0' + option pwrkey_gpio_pin '495' + option gsmpow_gpio_pin '-480' + option simdet_gpio_pin '497' + option simaddr_gpio_pin '496' + option simdet0_gpio_pin '493' + option simdet1_gpio_pin '494' + option csq_level '0' + option sim0_priority '1' + option sim0_apn 'internet' + option sim0_pincode '' + option sim0_username '' + option sim0_password '' + option sim0_testip '' + option sim1_priority '0' + option sim1_apn 'internet' + option sim1_pincode '' + option sim1_username '' + option sim1_password '' + option sim1_testip '' + option restart_services 'smstools3 gpsd' + option firststart '1' diff --git a/simman2/files/simman2.defaults b/simman2/files/simman2.defaults new file mode 100755 index 00000000..d0e73538 --- /dev/null +++ b/simman2/files/simman2.defaults @@ -0,0 +1,27 @@ +#!/bin/sh + +. /usr/share/libubox/jshn.sh +json_load "$(ubus call system board)" +json_get_var MODEL model +case "$MODEL" in + "TELEOFIS LT70") + uci set simman2.core.pwrkey_gpio_pin='527' + uci set simman2.core.gsmpow_gpio_pin='-512' + uci set simman2.core.simdet_gpio_pin='529' + uci set simman2.core.simaddr_gpio_pin='528' + uci set simman2.core.simdet0_gpio_pin='525' + uci set simman2.core.simdet1_gpio_pin='526' + uci commit simman2 + ;; + "TELEOFIS RTUx68" | "TELEOFIS RTUx68 RE-DE") + uci set simman2.core.pwrkey_gpio_pin='105' + uci set simman2.core.gsmpow_gpio_pin='83' + uci set simman2.core.simdet_gpio_pin='78' + uci set simman2.core.simaddr_gpio_pin='82' + uci set simman2.core.simdet0_gpio_pin='79' + uci set simman2.core.simdet1_gpio_pin='104' + uci commit simman2 + ;; +esac + +exit 0 diff --git a/simman2/files/simman2.init b/simman2/files/simman2.init new file mode 100755 index 00000000..97de8890 --- /dev/null +++ b/simman2/files/simman2.init @@ -0,0 +1,70 @@ +#!/bin/sh /etc/rc.common + +START=80 +STOP=10 +USE_PROCD=1 + +DIR=/sbin +PROG=simman2 + +error(){ + echo "${initscript}:" "$@" 1>&2 +} + +xappend() { + local filename="$1" + local value="$2" + echo "${value#--}" >> "$filename" +} + +modem_power_off() { + echo "simman2: power off $1 modem" > /dev/kmsg + simman2_cli -x $1 +} + +section_enabled(){ + config_get_bool enabled "$1" 'enabled' 0 + [ $enabled -gt 0 ] +} + +start_service_daemon(){ + local s="$1" + + section_enabled "$s" || return 1 + config_get ATDEVICE "$s" atdevice + config_get FIRSTSTART "$s" firststart + + if [[ "$FIRSTSTART" -eq "1" ]]; then + /etc/simman2/modeminit $ATDEVICE & + /etc/simman2/nbmodeminit & + uci_set simman2 "$1" firststart "0" + uci_commit simman2 + fi + + procd_open_instance + procd_set_param command $DIR/$PROG -c $s + procd_set_param respawn ${respawn_threshold:-360} ${respawn_timeout:-5} ${respawn_retry:-0} + procd_close_instance +} + +start_service(){ + mkdir -p /var/simman2/dev + config_load 'simman2' + config_foreach start_service_daemon 'simman2' +} + +service_triggers() +{ + procd_add_reload_trigger "simman2" +} + +reload_service() { + stop + start +} + +shutdown() { + stop + config_load 'simman2' + config_foreach modem_power_off 'simman2' +} diff --git a/simman2/files/simman2.rpcd b/simman2/files/simman2.rpcd new file mode 100644 index 00000000..c0525eb1 --- /dev/null +++ b/simman2/files/simman2.rpcd @@ -0,0 +1,31 @@ +#!/bin/sh + +. /usr/share/libubox/jshn.sh + +case "$1" in + list) + echo '{' + echo '"info": { "device": "str", "cmd": "str" },' + echo '"statusall": { "config": "str" }' + echo '}' + ;; + call) + case "$2" in + info) + # read the arguments + read input; + json_load "$input" + json_get_var device device + json_get_var cmd cmd + result=$(/sbin/simman2_cli -d $device $cmd) + echo "{ \"result\": \"$result\" }" + ;; + statusall) + read input; + json_load "$input" + json_get_var config config + /sbin/simman2_cli -a $config + ;; + esac + ;; +esac diff --git a/simman2/src/Makefile b/simman2/src/Makefile new file mode 100755 index 00000000..c72b5e62 --- /dev/null +++ b/simman2/src/Makefile @@ -0,0 +1,18 @@ +CC = gcc +CFLAGS = -O2 -Wall -Wmissing-declarations -g3 +LDLIBS = -luci -lubox + +PROGRAMS=simman2 simman2_cli + +all: $(PROGRAMS) + +simman2: simman.o common.o modem_ehs5.c modem_sim7600.o modem_a7600.o modem_sim5360.o modem_sim5300.o modem_common.o + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +simman2_cli: simman_cli.o common.o modem_ehs5.c modem_sim7600.o modem_a7600.o modem_sim5360.o modem_sim5300.o modem_common.o + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +clean: + rm -f *.o $(PROGRAMS) + + diff --git a/simman2/src/Makefile2 b/simman2/src/Makefile2 new file mode 100755 index 00000000..50b46204 --- /dev/null +++ b/simman2/src/Makefile2 @@ -0,0 +1,22 @@ +STAG_DIR = ./../../../staging_dir/target-arm_arm926ej-s_uClibc-0.9.33.2_eabi +CC = gcc +CFLAGS = -Os -Wall -Wmissing-declarations -g3 +CPPFLAGS = -I../inc -I./ -I$(STAG_DIR)/usr/include +LDFLAGS = -L$(STAG_DIR)/usr/lib -L./ + +LDLIBS = -luci + +PROGRAMS=simman2 simman2_cli + +all: $(PROGRAMS) + +simman2: simman.o common.o modem_ehs5.c modem_sim7600.o + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +simman2_cli: simman_cli.o common.o modem_ehs5.c modem_sim7600.o + $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) + +clean: + rm -f *.o $(PROGRAMS) + + diff --git a/simman2/src/common.c b/simman2/src/common.c new file mode 100755 index 00000000..25cd295e --- /dev/null +++ b/simman2/src/common.c @@ -0,0 +1,1059 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "dirent.h" +#include "uci.h" +#include + +#include +#include +#include + +#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + +static const struct modems_ops *modems[] = { + &ehs5_ops, + &sim7600_ops, + &a7600_ops, + &sim5360_ops, + &sim5300_ops, +}; + +//---------------------------------------------------------OLD---------------------- + +int ping(char *ip, char *iface) +{ + FILE *fp; + char b[128]; + char path[128] = {0}; + + char ph_iface[128] = {0}; + + if(iface == NULL) + sprintf(path,"/bin/ping -w5 -W5 -c1 -s8 %s | grep 'rec' | awk -F'[ ]' '{print $4}'",ip); + else + { + sprintf(path,"ubus call network.interface.%s status | grep l3_device", iface); + fp = popen(path,"r"); + if (fp == NULL) + { + pclose(fp); + return 0; + } + if ( fgets(ph_iface,sizeof(ph_iface)-1, fp) == NULL ) + { + pclose(fp); + return 0; + } + pclose(fp); + if(common_awk_f(ph_iface,"\"", 4)!=0) + sprintf(path,"/bin/ping -w5 -W5 -c1 -s8 -I %s %s | grep 'rec' | awk -F'[ ]' '{print $4}'", iface, ip); + else + sprintf(path,"/bin/ping -w5 -W5 -c1 -s8 -I %s %s | grep 'rec' | awk -F'[ ]' '{print $4}'", ph_iface, ip); + } + + fp = popen(path,"r"); + + if (fp == NULL) + { + pclose(fp); + return 0; + } + + if ( fgets(b,sizeof(b)-1, fp) == NULL ) + { + pclose(fp); + return 0; + } + + pclose(fp); + + return atoi(b); +} + + + +//---------------------------------------------------------OLD---------------------- + +int gpio_export(int16_t gpio) +{ + char buf[64]; + int fd, ret; + uint16_t igpio; + if(gpio<0){ + igpio = 0-gpio; + sprintf(buf, "/sys/class/gpio/gpio%d/value", igpio); + } else { + sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); + } + + if(access(buf, F_OK)==0) + { + return 0; + } + if((fd = open("/sys/class/gpio/export", O_WRONLY)) < 0) + { + return -1; + } + if(gpio<0){ + sprintf(buf, "%d", igpio); + } else { + sprintf(buf, "%d", gpio); + } + ret = write(fd, buf, strlen(buf)); + + close(fd); + return ret; +} + +int gpio_read(int16_t gpio) +{ + char buf[64]; + int fd, ret; + uint16_t igpio; + if(gpio<0){ + igpio = (uint16_t)(0-gpio); + sprintf(buf, "/sys/class/gpio/gpio%d/value", igpio); + } else { + sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); + } + + if((fd = open(buf, O_RDONLY)) < 0) + { + gpio_export(gpio); + if((fd = open(buf, O_RDONLY)) < 0) + return -1; + } + if((ret = read(fd, buf, 1)) > 0) + { + if(gpio<0) + { + if (*buf == '0') ret=1; + else + if (*buf == '1') ret=0; + } else { + if (*buf == '0') ret=0; + else + if (*buf == '1') ret=1; + } + } + + close(fd); + return ret; +} + +int gpio_set_direction(int16_t gpio, int dir) +{ + static const char s_directions_str[] = "in\0out"; + char buf[64]; + int fd; + if(gpio<0){ + uint16_t igpio = 0-gpio; + sprintf(buf, "/sys/class/gpio/gpio%d/direction", igpio); + } else { + sprintf(buf, "/sys/class/gpio/gpio%d/direction", gpio); + } + + if((fd = open(buf, O_WRONLY)) < 0) + { + gpio_export(gpio); + if((fd = open(buf, O_RDONLY)) < 0) + return -1; + } + + if(write(fd, &s_directions_str[IN == dir ? 0 : 3], IN == dir ? 2 : 3) == -1) { + return -1; + } + + close(fd); + return 0; +} + +int gpio_set_value(int16_t gpio, uint8_t value) +{ + char buf[64]; + int fd, ret; + if(gpio<0){ + uint16_t igpio = 0-gpio; + sprintf(buf, "/sys/class/gpio/gpio%d/value", igpio); + } else { + sprintf(buf, "/sys/class/gpio/gpio%d/value", gpio); + } + + if((fd = open(buf, O_WRONLY)) < 0) + { + gpio_export(gpio); + if((fd = open(buf, O_RDONLY)) < 0) + return -1; + } + gpio_set_direction(gpio, OUT); + if(gpio<0){ + if(value==0) + value=1; + else + value=0; + } + sprintf(buf, "%d", value); + ret = write(fd, buf, 1); + + close(fd); + return ret; +} + +const struct modems_ops * modems_backend(char *device) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(modems); i++) + if (modems[i]->probe(device)==0) + return modems[i]; + + return NULL; +} + + +int write_to_com(int fd, char *text) { + int res; + unsigned int a; + char ch; + for(a=0;a=254) { + //fixme: size of receive > b + receive[b++]=c; + receive[b+1]='\0'; + if(strstr(receive,text)!=NULL) break; + if(strstr(receive,"ERROR")!=NULL) break; + } + } + return receive; +} + + +int set_interface(int fd, int speed) +{ + struct termios tty; + memset (&tty, 0, sizeof tty); + if (tcgetattr (fd, &tty) != 0) + { + printf ("error %d from tcgetattr", errno); + return -1; + } + + tty.c_cflag &= ~PARENB; + tty.c_cflag &= ~CSTOPB; + tty.c_cflag &= ~CSIZE; + tty.c_cflag |= CS8; + tty.c_cflag &= ~CRTSCTS; + tty.c_cflag |= CREAD | CLOCAL; + tty.c_lflag &= ~ICANON; + tty.c_lflag &= ~ECHO; + tty.c_lflag &= ~ECHOE; + tty.c_lflag &= ~ECHONL; + tty.c_lflag &= ~ISIG; + tty.c_iflag &= ~(IXON | IXOFF | IXANY); + tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); + tty.c_oflag &= ~OPOST; + tty.c_oflag &= ~ONLCR; + tty.c_cc[VTIME] = 10; + tty.c_cc[VMIN] = 0; + + cfsetispeed(&tty, speed); + cfsetospeed(&tty, speed); + + if (tcsetattr(fd, TCSANOW, &tty) != 0) { + //printf("Error %i from tcsetattr: %s\n", errno, strerror(errno)); + return 1; + } + return 0; +} + +int cut_string(char *stringSource, char *stringStart, char *stringEnd){ + char *pStr; + + if(stringStart[0]!='\0'){ + pStr=strstr(stringSource,stringStart); + if(!pStr){ + return -1; + } + pStr+=(int)strlen(stringStart); + strcpy(stringSource,pStr); + } + + if(stringEnd[0]!='\0'){ + pStr=strstr(stringSource,stringEnd); + if(!pStr){ + return -1; + } + *pStr='\0'; + } + return 0; +} + +int modem_send_command(char *receive, char *device, char *at_command, char *wait_output){ + char fname[256]; + strcpy(fname,"/var/simman2"); + strcat(fname,device); + strcat(fname,".lock"); + if(access(fname,F_OK)==0){ + // fixme + sleep(1); + remove(fname); + } + + FILE *open_file=fopen(fname,"w"); + if(open_file!=NULL){ + fprintf(open_file,"ALL:"); + fclose(open_file); + } + int fd=open(device,O_RDWR|O_NOCTTY|O_SYNC); + if(set_interface(fd,115200)!=0){ + close(fd); + return -1; + } + if(write_to_com(fd,at_command)!=0){ + close(fd); + return -1; + } + wait_for(fd,wait_output,receive); + close(fd); + remove(fname); + + return 0; +} + +int modem_sim_state(char *receive, struct settings_entry *settings){ + int sim0_stat, sim1_stat, active_sim, res=0; + + sim0_stat=gpio_read(settings->simdet0_pin); + if (sim0_stat<0) + { + printf("sim0_detect read error: %d\n",sim0_stat); + return 1; + } + //printf("SIM0 status: %d\n",sim0_stat); + + sim1_stat=gpio_read(settings->simdet1_pin); + if (sim1_stat<0) + { + printf("sim1_detect read error: %d\n",sim1_stat); + return 1; + } + //printf("SIM1 status: %d\n",sim1_stat); + + active_sim=gpio_read(settings->simaddr_pin); + if (active_sim<0) + { + printf("active_sim read error: %d\n",active_sim); + return 1; + } + //printf("Active SIM: %d\n",active_sim); + + sprintf(receive,"1 %sINSERTED%s | 2 %sINSERTED%s",sim0_stat?"NOT ":"",active_sim?"":" (ACT)",sim1_stat?"NOT ":"",active_sim?" (ACT)":""); + + + return 0; +} + +int common_awk_f(char *source_str, char *delim, uint8_t num){ + uint16_t i=0; + char *ptr = strtok(source_str, delim); + while(ptr!=NULL) + { + if(++i==num){ + break; + } + ptr=strtok(NULL, delim); + } + //printf("'%s'\n", ptr); + if(i!=num){ + return -1; + } + strcpy(source_str,ptr); + return 0; +} + +char *uci_get_value(char *uci_path) +{ + char path[256]= {0}; + char buffer[256] = {0}; + struct uci_ptr ptr; + struct uci_context *c = uci_alloc_context(); + struct uci_element *e; + + if(!c) return NULL; + + strcpy(path, uci_path); + if ((uci_lookup_ptr(c, &ptr, path, true) != UCI_OK) || + (ptr.o==NULL || ptr.o->v.string==NULL)) + { + uci_free_context(c); + return NULL; + } + + switch(ptr.o->type) { + case UCI_TYPE_STRING: + strcpy(buffer, ptr.o->v.string); + break; + case UCI_TYPE_LIST: + uci_foreach_element(&ptr.o->v.list, e){ + strcat(buffer,e->name); + strcat(buffer," "); + } + break; + default: + return NULL; + break; + } + + uci_free_context(c); + + return strdup(buffer); +} + +int uci_set_value(char *section_name, char *option, char *value){ + + printf("Set %s.%s to %s\n",section_name,option,value); + +// char path[256]= {0}; +// struct uci_ptr ptr; +// struct uci_context *c = uci_alloc_context(); +// +// if(!c) return -1; +// +// strcpy(path, section_name); +// if (uci_lookup_ptr(c, &ptr, path, true) != UCI_OK) { +// uci_free_context(c); +// return -1; +// } +// +// ptr.option = option; +// ptr.value = (value)?(value):(""); +// +// if (uci_set(c, &ptr) != UCI_OK) +// uci_perror(c, "uci_set error"); +// +// //fixme "Child terminated with signal = 0xb (SIGSEGV)" +// if (uci_commit(c, &ptr.p, false) != UCI_OK) { +// uci_free_context(c); +// return -1; +// } +// +// uci_free_context(c); + + char cmd[256]; + if(value == NULL){ + sprintf(cmd,"uci set %s.%s='' && uci commit",section_name,option); + } else { + sprintf(cmd,"uci set %s.%s='%s' && uci commit",section_name,option,value); + } + system(cmd); + + return 0; +} + +int uci_read_configuration(struct settings_entry *set, char *config) +{ + char * p, path[128]; + char i,j; + + set->name = config; + + sprintf(path,"simman2.%s.pwrkey_gpio_pin",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading gsmpow_gpio_pin\n"); + return -1; + } + set->pwrkey_pin = atoi(p); + + sprintf(path,"simman2.%s.gsmpow_gpio_pin",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading gsmpow_gpio_pin\n"); + return -1; + } + set->gsmpow_pin = atoi(p); + + sprintf(path,"simman2.%s.simdet_gpio_pin",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading simdet_gpio_pin\n"); + return -1; + } + set->simdet_pin = atoi(p); + + sprintf(path,"simman2.%s.simaddr_gpio_pin",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading simaddr_gpio_pin\n"); + return -1; + } + set->simaddr_pin = atoi(p); + + sprintf(path,"simman2.%s.simdet0_gpio_pin",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading simdet0_gpio_pin\n"); + return -1; + } + set->simdet0_pin = atoi(p); + + sprintf(path,"simman2.%s.simdet1_gpio_pin",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading simdet1_gpio_pin\n"); + return -1; + } + set->simdet1_pin = atoi(p); + + sprintf(path,"simman2.%s.iface",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading interface\n"); + return -1; + } + set->iface = p; + + sprintf(path,"simman2.%s.only_first_sim",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading only_first_sim\n"); + return -1; + } + set->only_first_sim = atoi(p); + + sprintf(path,"simman2.%s.retry_num",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading retry_num\n"); + return -1; + } + set->retry_num = atoi(p); + + sprintf(path,"simman2.%s.check_period",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading check_period\n"); + return -1; + } + set->check_period = atoi(p); + + sprintf(path,"simman2.%s.delay",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading delay\n"); + return -1; + } + set->delay = atoi(p); + + sprintf(path,"simman2.%s.csq_level",config); + if ((p = uci_get_value(path)) == NULL) + { + set->csq_level = 0; + } + set->csq_level = atoi(p); + + sprintf(path,"simman2.%s.sw_before_modres",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading sw_before_modres\n"); + set->sw_before_modres = 0; + return -1; + } + set->sw_before_modres = atoi(p); + + if(set->sw_before_modres > 100) + set->sw_before_modres = 100; + else if(set->sw_before_modres < 0) + set->sw_before_modres = 0; + + sprintf(path,"simman2.%s.sw_before_sysres",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading sw_before_sysres\n"); + set->sw_before_sysres = 0; + return -1; + } + + set->sw_before_sysres = atoi(p); + if(set->sw_before_sysres > 100) + set->sw_before_sysres = 100; + else if(set->sw_before_sysres < 0) + set->sw_before_sysres = 0; + + sprintf(path,"simman2.%s.testip",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading testip\n"); + return -1; + } + + char *tok = strtok(p," "); + + for (i = 0; i < sizeof(set->serv)/sizeof(set->serv[0]); i++) + { + set->serv[i].ip = NULL; + set->serv[i].retry_check = 0; + set->serv[i].sim_num = NULL; + } + + i = 0; + while(tok && i < sizeof(set->serv)/sizeof(set->serv[0])) + { + set->serv[i].sim_num = 2; + set->serv[i++].ip = tok; + tok = strtok(NULL," "); + } + j = i; + for (i = 0; i < sizeof(set->sim)/sizeof(set->sim[0]); i++) + { + set->sim[i].init = 0; + + sprintf(path,"simman2.%s.sim%d_priority",config,i); + if ((p = uci_get_value(path)) == NULL) + { + //fprintf(stderr,"Error reading sim%d_priority\n",i); + continue; + } + set->sim[i].prio = atoi(p); + + sprintf(path,"simman2.%s.sim%d_mode",config,i); + if ((p = uci_get_value(path)) == NULL) + { + //fprintf(stderr,"Error reading sim%d_mode\n",i); + set->sim[i].mode = NULL; + } else + set->sim[i].mode = p; + + sprintf(path,"simman2.%s.sim%d_testip",config,i); + if ((p = uci_get_value(path)) != NULL) + { + char *tok = strtok(p," "); + while(tok && j < sizeof(set->serv)/sizeof(set->serv[0])) + { + set->serv[j].sim_num = i; + set->serv[j++].ip = tok; + tok = strtok(NULL," "); + } + } + sprintf(path,"simman2.%s.sim%d_apn",config,i); + if ((p = uci_get_value(path)) == NULL) + { + //fprintf(stderr,"Error reading sim%d_apn\n",i); + set->sim[i].apn = NULL; + } else + set->sim[i].apn = p; + + sprintf(path,"simman2.%s.sim%d_auth",config,i); + if ((p = uci_get_value(path)) == NULL) + { + //fprintf(stderr,"Error reading sim%d_auth\n",i); + set->sim[i].auth = NULL; + } else + set->sim[i].auth = p; + + sprintf(path,"simman2.%s.sim%d_username",config,i); + if ((p = uci_get_value(path)) == NULL) + { + //fprintf(stderr,"Error reading sim%d_username\n",i); + set->sim[i].user = NULL; + } else + set->sim[i].user = p; + + sprintf(path,"simman2.%s.sim%d_password",config,i); + if ((p = uci_get_value(path)) == NULL) + { + //fprintf(stderr,"Error reading sim%d_password\n",i); + set->sim[i].pass = NULL; + } else + set->sim[i].pass = p; + + sprintf(path,"simman2.%s.sim%d_pincode",config,i); + if ((p = uci_get_value(path)) == NULL) + { + //fprintf(stderr,"Error reading sim%d_pincode\n",i); + set->sim[i].pin = NULL; + } else + set->sim[i].pin = p; + + set->sim[i].init = 1; + } + + if (!(set->sim[0].init || set->sim[1].init)) + { + fprintf(stderr,"No find SIM card info\n"); + return -1; + } + + sprintf(path,"simman2.%s.atdevice",config); + if ((p = uci_get_value(path)) == NULL) + { + fprintf(stderr,"Error reading atdevice\n"); + return -1; + } + set->atdevice = p; + + sprintf(path,"simman2.%s.restart_services",config); + if ((p = uci_get_value(path)) != NULL) + set->restart_services=p; + else + set->restart_services=NULL; + +// fprintf(stderr,"retry_num=%d, check_period=%d, delay=%d, atdevice=%s, gsmpow_pin=%d, simdet_pin=%d, simaddr_pin=%d, simdet0_pin=%d, simdet1_pin=%d, ", +// set->retry_num, +// set->check_period, +// set->delay, +// set->atdevice, +// set->gsmpow_pin, set->simdet_pin, set->simaddr_pin, set->simdet0_pin, set->simdet1_pin ); + for (i = 0; i < sizeof(set->serv)/sizeof(set->serv[0]);i++) + if (set->serv[i].ip) +// fprintf(stderr,"%s ",set->serv[i].ip); + +// fprintf(stderr,"\n"); + return 0; +} + +char *modem_summary(struct modems_ops *modem, uint8_t InfoParam, char *dev) +{ + FILE *fp; + char b[256] = {0}; + char cmd[256] = {0}; + char *defval = "error"; + +// struct settings_entry settings; + + + switch(InfoParam) + { + case INFO_MODEM: + modem->name(b,dev); + break; + case INFO_FW: + modem->version(b,dev); + break; + // case INFO_SIM: + // uci_read_configuration(&settings,config); + // modem_sim_state(b,&settings); + // break; + case INFO_CCID: + if(modem->ccid(b,dev)){ + strcpy(b,"NONE"); + }; + break; + case INFO_IMSI: + if(modem->imsi(b,dev)){ + strcpy(b,"NONE"); + }; + break; + case INFO_PINSTAT: + modem->pin_state(b,dev); + break; + case INFO_SIGLEV: + modem->csq(b,dev); + break; + case INFO_REGSTAT: + modem->registration(b,dev); + break; + case INFO_BASESTID: + modem->bs_info(b,dev); + break; + case INFO_BASESTBW: + modem->band_info(b,dev); + break; + case INFO_NETTYPE: + modem->network_type(b,dev); + break; + case INFO_GPRSSTAT: + modem->data_registration(b,dev); + break; + case INFO_PACKTYPE: + modem->data_type(b,dev); + break; + case INFO_OP: + modem->operator(b,dev); + break; + case INFO_IMEI: + if(modem->imei(b,dev)){ + strcpy(b,"NONE"); + }; + break; + default: + return strdup(defval); + } + + return strdup(b); +} + +int modem_gpio_export(struct settings_entry *settings){ + int res=0; + + res=gpio_export(settings->pwrkey_pin); + if (res<0) + { + printf("pwrkey_pin export error: %d\n",res); + return 1; + } + + res=gpio_export(settings->gsmpow_pin); + if (res<0) + { + printf("gsmpow_pin export error: %d\n",res); + return 1; + } + + res=gpio_export(settings->simdet_pin); + if (res<0) + { + printf("simdet_pin export error: %d\n",res); + return 1; + } + + res=gpio_export(settings->simaddr_pin); + if (res<0) + { + printf("simaddr_pin export error: %d\n",res); + return 1; + } + + res=gpio_export(settings->simdet0_pin); + if (res<0) + { + printf("sim0_detect export error: %d\n",res); + return 1; + } + + res=gpio_export(settings->simdet1_pin); + if (res<0) + { + printf("simdet1_pin export error: %d\n",res); + return 1; + } + + return 0; +} + +int ubus_interface_up(uint8_t *iface){ + char cmd[256]; + sprintf(cmd,"ubus call network.interface.%s up",iface); + system(cmd); + printf("Interface %s up\n",iface); + return 0; +} + +int ubus_interface_down(uint8_t *iface){ + char cmd[256]; + sprintf(cmd,"ubus call network.interface.%s down",iface); + system(cmd); + printf("Interface %s down\n",iface); + return 0; +} + +int ubus_network_reload(void){ + system("ubus call network reload"); + return 0; +} + +int services_stop(uint8_t *services){ + char service_stop_cmd[256]; + char services_copy[256]; + if(services!=NULL){ + strcpy(services_copy,services); + char *tok = strtok(services_copy," "); + while(tok) + { + sprintf(service_stop_cmd,"/etc/init.d/%s stop",tok); + system(service_stop_cmd); + tok = strtok(NULL," "); + } + } + return 0; +} + +int services_start(uint8_t *services){ + char service_start_cmd[256]; + char services_copy[256]; + if(services!=NULL){ + strcpy(services_copy,services); + char *tok = strtok(services_copy," "); + while(tok) + { + sprintf(service_start_cmd,"/etc/init.d/%s start",tok); + system(service_start_cmd); + tok = strtok(NULL," "); + } + } + return 0; +} + +int modem_sim_up(uint8_t *iface){ + //fixme + printf("Modem specific command start %s \n",iface); + return 0; +} + +int modem_sim_down(uint8_t *iface){ + //fixme + printf("Modem specific command stop %s \n",iface); + return 0; +} + +int switch_sim(struct settings_entry *settings, struct modems_ops *modem, uint8_t sim_n, uint8_t first_start){ + uint8_t sim0_stat, sim1_stat, active_sim, res=0; + char buf[256]={0}; + char buf2[256]={0}; + + printf("attempt to switch to SIM%d\n", sim_n+1); + res=gpio_set_direction(settings->simdet0_pin,0); + if (res!=0) + { + printf("sim0_detect direction error: %d\n",res); + return 1; + } + + res=gpio_set_direction(settings->simdet1_pin,0); + if (res!=0) + { + printf("sim1_detect direction error: %d\n",res); + return 1; + } + + sim0_stat=gpio_read(settings->simdet0_pin); + if (sim0_stat<0) + { + printf("sim0_detect read error: %d\n",sim0_stat); + return 1; + } + printf("SIM0 status: %d\n",sim0_stat); + + sim1_stat=gpio_read(settings->simdet1_pin); + if (sim1_stat<0) + { + printf("sim1_detect read error: %d\n",sim1_stat); + return 1; + } + printf("SIM1 status: %d\n",sim1_stat); + + active_sim=gpio_read(settings->simaddr_pin); + if (active_sim<0) + { + printf("active_sim read error: %d\n",active_sim); + return 1; + } + printf("Active SIM: %d\n",active_sim); + + if (sim0_stat==1 && sim1_stat==1){ + //fixme log + printf("Both SIM cards are not inserted\n"); + gpio_set_value(settings->simdet_pin,0); + ubus_interface_down(settings->iface); + return 0; + } + + if ((sim_n==0 && sim0_stat==1) || (sim_n==1 && sim1_stat==1)){ + //fixme log + printf("Not inserted SIM %d, switch to inserted sim\n",sim_n+1); + if(sim_n==0){ + sim_n=1; + } else { + sim_n=0; + } + } + + ubus_interface_down(settings->iface); + sleep(2); + //fixme + sprintf(buf,"network.%s",settings->iface); + + sprintf(buf2,"simman2.%s.sim%d_apn",settings->name,sim_n); + uci_set_value(buf,"apn",uci_get_value(buf2)); + + sprintf(buf2,"simman2.%s.sim%d_pincode",settings->name,sim_n); + uci_set_value(buf,"pincode",uci_get_value(buf2)); + + if (modem != &a7600_ops) { + sprintf(buf2,"simman2.%s.sim%d_auth",settings->name,sim_n); + uci_set_value(buf,"auth",uci_get_value(buf2)); + + sprintf(buf2,"simman2.%s.sim%d_username",settings->name,sim_n); + uci_set_value(buf,"username",uci_get_value(buf2)); + + sprintf(buf2,"simman2.%s.sim%d_password",settings->name,sim_n); + uci_set_value(buf,"password",uci_get_value(buf2)); + } + + sprintf(buf2,"simman2.%s.sim%d_mode",settings->name,sim_n); + uci_set_value(buf,"modes",uci_get_value(buf2)); + + system("uci commit network"); + + services_stop(settings->restart_services); + //fixme + modem->sim_pullout(settings); + + gpio_set_value(settings->simdet_pin,0); + usleep(500); + if (sim_n==active_sim && first_start == 0){ + //fixme log + printf("SIM %d is already active\n",sim_n+1); + //ubus_network_reload(); + //ubus_interface_up(settings->iface); + //return 0; + } else { + gpio_set_value(settings->simaddr_pin,sim_n); + } + sleep(3); + gpio_set_value(settings->simdet_pin,1); + usleep(500); + modem->set_pin(settings,settings->sim[sim_n].pin); + modem->set_mode(settings,settings->sim[sim_n].mode); + modem->set_auth(settings,settings->sim[sim_n].auth,settings->sim[sim_n].user,settings->sim[sim_n].pass); + modem->set_apn(settings,settings->sim[sim_n].apn); + + //fixme + modem->sim_pullup(settings); + services_start(settings->restart_services); + ubus_network_reload(); + ubus_interface_up(settings->iface); + return 0; +} diff --git a/simman2/src/common.h b/simman2/src/common.h new file mode 100755 index 00000000..b59a60a4 --- /dev/null +++ b/simman2/src/common.h @@ -0,0 +1,146 @@ +#ifndef _common_h +#define _common_h + +#include +#include + +#define INFO_SIM 0 +#define INFO_CCID 1 +#define INFO_PINSTAT 2 +#define INFO_SIGLEV 3 +#define INFO_REGSTAT 4 +#define INFO_BASESTID 5 +#define INFO_BASESTBW 6 +#define INFO_NETTYPE 7 +#define INFO_GPRSSTAT 8 +#define INFO_PACKTYPE 9 +#define INFO_IMEI 10 +#define INFO_MODEM 11 +#define INFO_IMSI 12 +#define INFO_FW 13 +#define INFO_ALL 14 +#define POWER_OFF 15 +#define POWER_UP 16 +#define INFO_OP 17 + +#define IN 0 +#define OUT 1 +#define LOW 0 +#define HIGH 1 + +#define LOG(fmt, ...) do { \ + syslog(LOG_NOTICE,"simman: "fmt, ## __VA_ARGS__); \ + fprintf(stderr, "simman: "fmt, ## __VA_ARGS__); \ + } while (0) + +#define ERROR(fmt, ...) do { \ + syslog(LOG_ERR,"simman: "fmt, ## __VA_ARGS__); \ + fprintf(stderr, "simman: "fmt, ## __VA_ARGS__); \ + } while (0) + +int ping(char *ip, char *iface); + +typedef struct testip{ + uint8_t *ip; + uint16_t retry_check; + uint8_t sim_num; // 0 - sim0, 1 - sim1, 2 - both +}testip_t; + +typedef struct sim_s +{ + uint8_t init; + uint8_t prio; + uint8_t *pin; + uint8_t *auth; + uint8_t *user; + uint8_t *pass; + uint8_t *apn; + uint8_t *mode; +}sim_t; + +struct settings_entry{ + uint8_t *name; + uint8_t only_first_sim; + uint8_t retry_num; + uint16_t check_period; + uint16_t delay; + uint16_t csq_level; + testip_t serv[8]; + sim_t sim[2]; + uint8_t *atdevice; + uint8_t *iface; + uint16_t sw_before_modres; + uint16_t sw_before_sysres; + uint8_t *imei; + uint8_t *ccid; + int16_t pwrkey_pin; + int16_t gsmpow_pin; + int16_t simdet_pin; + int16_t simaddr_pin; + int16_t simdet0_pin; + int16_t simdet1_pin; + uint8_t *restart_services; +}; + +struct modems_ops{ + int (*name)(char *,char *); + int (*probe)(char *); + int (*init)(struct settings_entry *); + int (*version)(char *,char *); + int (*imei)(char *,char *); + int (*ccid)(char *,char *); + int (*pin_state)(char *,char *); + int (*csq)(char *,char *); + int (*bs_info)(char *,char *); + int (*registration)(char *,char *); + int (*band_info)(char *,char *); + int (*network_type)(char *,char *); + int (*data_registration)(char *,char *); + int (*data_type)(char *,char *); + int (*operator)(char *,char *); + int (*sim_pullout)(struct settings_entry *); + int (*sim_pullup)(struct settings_entry *); + int (*power_down)(struct settings_entry *); + int (*power_up)(struct settings_entry *); + int (*set_mode)(struct settings_entry *, char *); + int (*set_apn)(struct settings_entry *, char *); + int (*set_pin)(struct settings_entry *, char *); + int (*set_auth)(struct settings_entry *, char *, char *, char *); + int (*imsi)(char *,char *); +}; + +extern struct modems_ops ehs5_ops; +extern struct modems_ops a7600_ops; +extern struct modems_ops sim7600_ops; +extern struct modems_ops sim5360_ops; +extern struct modems_ops sim5300_ops; + +int modem_common_send_at(char *device); +int modem_common_pin_state(char *receive, char *device); +int modem_common_csq(char *receive, char *device); +int modem_common_imsi(char *receive, char *device); +int modem_common_registration(char *receive, char *device); +int modem_common_data_registration(char *receive, char *device); +int modem_common_operator(char *receive, char *device); +int modem_common_exist(char *device); +int modem_common_power_down(struct settings_entry *settings, struct modems_ops *modem); +int modem_common_power_up(struct settings_entry *settings, struct modems_ops *modem); +int modem_common_power_reset(struct settings_entry *settings, struct modems_ops *modem); +int modem_common_sim_pullout(struct settings_entry *settings); +int modem_common_sim_pullup(struct settings_entry *settings); +int modem_common_set_mode(struct settings_entry *settings, char *mode); +int modem_common_set_apn(struct settings_entry *settings, char *apn); +int modem_common_set_pin(struct settings_entry *settings, char *pin); +int modem_common_set_auth(struct settings_entry *settings, char *auth, char *user, char *pass); + +int modem_send_command(char *receive, char *device, char *at_command, char *wait_output); +int common_awk_f(char *source_str, char *delim, uint8_t num); +int switch_sim(struct settings_entry *settings, struct modems_ops *modem, uint8_t sim_n, uint8_t first_start); +int services_stop(uint8_t *services); +int gpio_read(int16_t gpio); +int gpio_set_value(int16_t gpio, uint8_t value); +char *uci_get_value(char *uci_path); +char *modem_summary(struct modems_ops *modem, uint8_t InfoParam, char *dev); + +#endif + diff --git a/simman2/src/modem_a7600.c b/simman2/src/modem_a7600.c new file mode 100755 index 00000000..5357a90a --- /dev/null +++ b/simman2/src/modem_a7600.c @@ -0,0 +1,486 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + +int a7600_name(char *receive, char *device){ + strcpy(receive,"SIMCOM A7602E-H"); + return 0; +} + +int a7600_probe(char *device){ + char receive[256]={0}; + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rATI\r","OK")!=0){ + return -1; + } + if(strstr(receive,"A7600E-HNVD")==NULL && strstr(receive,"A7600E-HNVW")==NULL && strstr(receive,"A7602E-H")==NULL){ + return -1; + } + + return 0; +} + +int a7600_init(struct settings_entry *settings){ + char buf[256]={0}; + uint8_t reset=0; + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + + if(modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPON?\r","OK")!=0) + { + return -1; + } + + if(strstr(buf,"+UIMHOTSWAPON: 1")==NULL) + { + modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPON=1\r","OK"); + reset=1; + } + + memset(buf,0,sizeof(buf)); + + modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPLEVEL?\r","OK"); + if(strstr(buf,"+UIMHOTSWAPLEVEL: 1")==NULL) + { + modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPLEVEL=1\r","OK"); + reset=1; + } + + memset(buf,0,sizeof(buf)); + + if(modem_send_command(buf,settings->atdevice,"\rAT+DIALMODE?\r","OK")!=0) + { + return -1; + } + + if(strstr(buf,"+DIALMODE: 0")==NULL) + { + modem_send_command(buf,settings->atdevice,"\rAT+DIALMODE=0\r","OK"); + reset=1; + } + + memset(buf,0,sizeof(buf)); + + if(modem_send_command(buf,settings->atdevice,"\rAT+USBNETIP?\r","OK")!=0) + { + return -1; + } + + if(strstr(buf,"+USBNETIP: 1")==NULL) + { + modem_send_command(buf,settings->atdevice,"\rAT+USBNETIP=1\r","OK"); + reset=1; + } + + if(reset) + { + modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPON=1\r","OK"); + modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPLEVEL=1\r","OK"); + a7600_power_down(settings); + a7600_power_up(settings); + } + + return 0; +} + +int a7600_version(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CGMR\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "+CGMR: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + return 0; +} + +int a7600_ccid(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CICCID\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "+ICCID: ", "\r")!=0){ + strcpy(receive,"ERROR"); + } + receive[strlen(receive)-2]='\0'; + return 0; +} + +int a7600_bs_info(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CPSI?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "CPSI: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(common_awk_f(receive,",",5)!=0){ + strcpy(receive,"ERROR"); + } + + return 0; +} + +int a7600_network_type(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CPSI?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "CPSI: ", ",")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + return 0; +} + +int a7600_band_info(char *receive, char *device){ + char buf[256]={0}; + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(buf,device,"\rAT+CPSI?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(buf, "CPSI: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + switch(buf[0]){ + case 'L': //LTE + if(common_awk_f(buf,",", 8)!=0){ + strcpy(receive,"ERROR"); + return 0; + } + strcpy(receive,"EARFCN "); + break; + case 'W': //WCDMA + if(common_awk_f(buf,",", 8)!=0){ + strcpy(receive,"ERROR"); + return 0; + } + strcpy(receive,"UARFCN "); + break; + case 'G': //GSM + if(common_awk_f(buf,",", 6)!=0){ + strcpy(receive,"ERROR"); + return 0; + } + strcpy(receive,"ARFCN "); + break; + default: + strcpy(receive,"ERROR"); + return 0; + } + + strcat(receive,buf); + return 0; +} + + +int a7600_data_type(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CNSMOD?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "+CNSMOD: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, ",","")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + switch(receive[0]){ + case '0': strcpy(receive,"No service"); break; + case '1': strcpy(receive,"GSM"); break; + case '2': strcpy(receive,"GPRS"); break; + case '3': strcpy(receive,"EGPRS (EDGE)"); break; + case '4': strcpy(receive,"WCDMA"); break; + case '5': strcpy(receive,"HSDPA only (WCDMA)"); break; + case '6': strcpy(receive,"HSUPA only (WCDMA)"); break; + case '7': strcpy(receive,"HSPA (HSDPA and HSUPA, WCDMA)"); break; + case '8': strcpy(receive,"LTE"); break; + default: strcpy(receive,"UNKNOWN"); break; + } + + return 0; +} + +int a7600_imei(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CGSN\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + while(receive[0] && !isdigit(receive[0])){ + strcpy(receive, receive +1); + } + if(cut_string(receive, "", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + return 0; +} + +int a7600_imsi(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CIMI\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + while(receive[0] && !isdigit(receive[0])){ + strcpy(receive, receive +1); + } + if(cut_string(receive, "", "\r\n")!=0){ + strcpy(receive,"ERROR"); + } + return 0; +} + +int a7600_power_down(struct settings_entry *settings){ + char buf[256]={0}; + char count=0; + + ubus_interface_down(settings->iface); + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + modem_send_command(buf,settings->atdevice,"\rAT+CPOF\r","OK"); + + while(count<=30) + { + if(modem_common_exist(settings->atdevice)==-1){ + break; + } + count++; + sleep(1); + } + + if(count==30){ + return -1; + } + gpio_set_value(settings->gsmpow_pin,HIGH); + sleep(1); + + return 0; +} + +int a7600_power_up(struct settings_entry *settings){ + uint8_t count=0; + gpio_set_value(settings->pwrkey_pin,HIGH); + usleep(500); + gpio_set_value(settings->gsmpow_pin,LOW); + while(count<=45){ + count++; + if(modem_common_exist(settings->atdevice)==0){ + return 0; + } + sleep(1); + } + if(count==45){ + return -1; + } + + return 0; +} + +int a7600_set_mode(struct settings_entry *settings,char *mode){ + char receive[256]={0}; + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + + if(mode == NULL){ + if(modem_send_command(receive,settings->atdevice,"\rAT+CNMP=2\r","OK")!=0) + return -1; + } else { + switch(mode[0]){ + case 'l': //LTE + if(modem_send_command(receive,settings->atdevice,"\rAT+CNMP=38\r","OK")!=0) + return -1; + break; + case 'u': //UMTS + if(modem_send_command(receive,settings->atdevice,"\rAT+CNMP=14\r","OK")!=0) + return -1; + break; + case 'g': //GSM + if(modem_send_command(receive,settings->atdevice,"\rAT+CNMP=13\r","OK")!=0) + return -1; + break; + default: //ALL MODES + if(modem_send_command(receive,settings->atdevice,"\rAT+CNMP=2\r","OK")!=0) + return -1; + break; + } + } + return 0; +} + +int a7600_set_apn(struct settings_entry *settings,char *apn){ + char receive[256]={0},buf[256]={0}; + + if(apn != NULL){ + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + sprintf(buf,"\rAT+CGDCONT=1,\"IP\",\"%s\"\r",apn); + if(modem_send_command(receive,settings->atdevice,buf,"OK")!=0) + return -1; + } + return 0; +} + +int a7600_set_pin(struct settings_entry *settings,char *pin){ + char receive[256]={0},buf[256]={0}; + int count=0; + + if(pin != NULL){ + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + + while(strstr(receive,"ISIMAID:")==NULL){ + memset(receive,0,sizeof(receive)); + modem_send_command(receive,settings->atdevice,"\rAT\r","OK"); + if(count++>10){ + break; + } + sleep(1); + } + count=0; + while(strstr(receive,"+CPIN:")==NULL){ + memset(receive,0,sizeof(receive)); + modem_send_command(receive,settings->atdevice,"\rAT+CPIN?\r","OK"); + if(count++>10){ + break; + } + usleep(500); + } + + if(strstr(receive,"+CPIN: SIM PIN")!=NULL) + { + sprintf(buf,"\rAT+CPIN=%s\r",pin); + if(modem_send_command(receive,settings->atdevice,buf,"+CPIN: READY")!=0) + return -1; + } + } + return 0; +} + +int a7600_set_auth(struct settings_entry *settings,char *auth, char *user,char *pass){ + char receive[256]={0},buf[256]={0}; + uint8_t auth_num = 2; + + if(user != NULL && pass != NULL){ + if(auth == NULL) + auth = "b"; + + switch(auth[0]){ + case 'n': //none + auth_num = 0; + break; + case 'p': //pap + auth_num = 1; + break; + case 'c': //chap + auth_num = 2; + break; + case 'b': //both + auth_num = 3; + break; + default: + auth_num = 2; + break; + } + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + // looks like the order of "user" and "pass" does not match with datasheet + sprintf(buf,"\rAT+CGAUTH=1,%d,\"%s\",\"%s\"\r",auth_num,pass,user); + if(modem_send_command(receive,settings->atdevice,buf,"OK")!=0) + return -1; + } else { + modem_send_command(receive,settings->atdevice,"\rAT+CGAUTH=1,0\r","OK"); + } + return 0; +} + +struct modems_ops a7600_ops = { + .name = a7600_name, + .init = a7600_init, + .probe = a7600_probe, + .version = a7600_version, + .imei = a7600_imei, + .ccid = a7600_ccid, + .imsi = a7600_imsi, + .pin_state = modem_common_pin_state, + .csq = modem_common_csq, + .bs_info = a7600_bs_info, + .registration = modem_common_registration, + .band_info = a7600_band_info, + .network_type = a7600_network_type, + .data_registration = modem_common_data_registration, + .operator = modem_common_operator, + .data_type = a7600_data_type, + .sim_pullout = modem_common_sim_pullout, + .sim_pullup = modem_common_sim_pullup, + .power_down = a7600_power_down, + .power_up = a7600_power_up, + .set_mode = a7600_set_mode, + .set_apn = a7600_set_apn, + .set_pin = a7600_set_pin, + .set_auth = a7600_set_auth +}; diff --git a/simman2/src/modem_common.c b/simman2/src/modem_common.c new file mode 100755 index 00000000..ab727bab --- /dev/null +++ b/simman2/src/modem_common.c @@ -0,0 +1,272 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + +int modem_common_send_at(char *device){ + char buf[256]={0}; + uint8_t i=0; + + while(i<5){ + if(modem_send_command(buf,device,"\rAT\r","OK")==0){ + return 0; + }; + i++; + usleep(500); + } + return -1; +} + +int modem_common_pin_state(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"NOT READY"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CPIN?\r","OK")!=0){ + strcpy(receive,"NOT READY"); + return -1; + } + if(cut_string(receive, "CPIN: ", "\r")!=0){ + strcpy(receive,"NOT READY"); + } + return 0; +} + +int modem_common_csq(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"99"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CSQ\r","OK")!=0){ + strcpy(receive,"99"); + return -1; + } + if(cut_string(receive, "CSQ: ", ",")!=0){ + strcpy(receive,"99"); + return -1; + } + return 0; +} + +int modem_common_registration(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CREG?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "CREG: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, ",","")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + switch(receive[0]){ + case '0': strcpy(receive,"NOT REGISTERED"); break; + case '1': strcpy(receive,"REGISTERED, HOME"); break; + case '2': strcpy(receive,"NOT REGISTERED, OPERATOR SEARCH"); break; + case '3': strcpy(receive,"REGISTRATION DENIED"); break; + case '5': strcpy(receive,"REGISTERED, ROAMING!"); break; + case '4': + default: strcpy(receive,"UNKNOWN"); break; + } + return 0; +} + +int modem_common_data_registration(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CGREG?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "CGREG: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return 0; + } + if(cut_string(receive, ",","")!=0){ + strcpy(receive,"ERROR"); + return 0; + } + + switch(receive[0]){ + case '0': strcpy(receive,"NOT REGISTERED"); break; + case '1': strcpy(receive,"REGISTERED, HOME"); break; + case '2': strcpy(receive,"NOT REGISTERED, OPERATOR SEARCH"); break; + case '3': strcpy(receive,"REGISTRATION DENIED"); break; + case '5': strcpy(receive,"REGISTERED, ROAMING!"); break; + case '4': + default: strcpy(receive,"UNKNOWN"); break; + } + + return 0; +} + +int modem_common_operator(char *receive, char *device){ + char operator[128]; + char mcc[128]; + + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+COPS=0,0\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(operator,device,"\rAT+COPS?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(cut_string(operator, "\"", "\",")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+COPS=0,2\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(mcc,device,"\rAT+COPS?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(cut_string(mcc, "\"", "\",")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + sprintf(receive,"%s (%s)",operator,mcc); + return 0; +} + +int modem_common_imsi(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CIMI\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "\r\n", "\r\n")!=0){ + strcpy(receive,"ERROR"); + } + return 0; +} + +int modem_common_exist(char *device){ + // 0 - OK, -1 - not found + return access(device, F_OK); +} + +int modem_common_power_down(struct settings_entry *settings, struct modems_ops *modem){ + uint8_t count=0; + + if(modem!=NULL) + { + modem->power_down(settings); + } + + gpio_set_value(settings->gsmpow_pin,HIGH); + while(count<=30) + { + if(modem_common_exist(settings->atdevice)==-1){ + return 0; + } + count++; + sleep(1); + } + + if(count==30){ + return -1; + } + + return 0; +} + +int modem_common_power_up(struct settings_entry *settings, struct modems_ops *modem){ + uint8_t count=0; + //fixme pwrkey + if(modem!=NULL) + { + modem->power_up(settings); + } + gpio_set_value(settings->pwrkey_pin,HIGH); + sleep(1); + gpio_set_value(settings->gsmpow_pin,LOW); + while(count<=45){ + if(modem_common_exist(settings->atdevice)==0){ + return 0; + } + count++; + sleep(1); + } + + if(count==45){ + return -1; + } + + return 0; +} + +int modem_common_power_reset(struct settings_entry *settings, struct modems_ops *modem){ + ubus_interface_down(settings->iface); + services_stop(settings->restart_services); + sleep(1); + if(modem_common_power_down(settings,modem)!=0){ + return -1; + } + sleep(3); + if(modem_common_power_up(settings,modem)!=0){ + return -1; + } + sleep(1); + return 0; +} + +int modem_common_sim_pullout(struct settings_entry *settings){ + return 0; +} + +int modem_common_sim_pullup(struct settings_entry *settings){ + return 0; +} + +int modem_common_set_mode(struct settings_entry *settings, char *mode){ + return 0; +} + +int modem_common_set_apn(struct settings_entry *settings, char *apn){ + return 0; +} + +int modem_common_set_pin(struct settings_entry *settings, char *pin){ + return 0; +} + +int modem_common_set_auth(struct settings_entry *settings, char *auth, char *user, char *pass){ + return 0; +} diff --git a/simman2/src/modem_ehs5.c b/simman2/src/modem_ehs5.c new file mode 100755 index 00000000..3afcc588 --- /dev/null +++ b/simman2/src/modem_ehs5.c @@ -0,0 +1,228 @@ +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + +int ehs5_name(char *receive, char *device){ + strcpy(receive,"Cinterion EHS5-E"); + return 0; +} + +int ehs5_probe(char *device){ + char receive[256]={0}; + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rATI\r","OK")!=0){ + return -1; + } + if(strstr(receive,"EHS5-E")==NULL){ + return -1; + } + return 0; +} + +int ehs5_init(struct settings_entry *settings){ + return 0; +} + +int ehs5_version(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rATI\r","OK")!=0){ + return -1; + } + if(cut_string(receive, "REVISION ", "\r")!=0){ + return -1; + } + return 0; +} + +int ehs5_ccid(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CCID\r","OK")!=0){ + return -1; + } + if(cut_string(receive, "CCID: ", "\r")!=0){ + strcpy(receive,"ERROR"); + } + return 0; +} + +int ehs5_bs_info(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rAT^SMONI\r","OK")!=0){ + return -1; + } + if(cut_string(receive, "SMONI: ", "\r")!=0){ + return -1; + } + + switch(receive[0]){ + case '2': + if(common_awk_f(receive,",", 7)!=0){ + strcpy(receive,"SEARCH"); + } + break; + case '3': + if(common_awk_f(receive,",", 9)!=0){ + strcpy(receive,"SEARCH"); + } + break; + default: + strcpy(receive,"SEARCH"); + return 0; + } + + return 0; +} + +int ehs5_network_type(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rAT^SMONI\r","OK")!=0){ + return -1; + } + if(cut_string(receive, "SMONI: ", ",")!=0){ + return -1; + } + return 0; +} + +int ehs5_band_info(char *receive, char *device){ + char buf[256]={0}; + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(buf,device,"\rAT^SMONI\r","OK")!=0){ + return -1; + } + if(cut_string(buf, "SMONI: ", "\r")!=0){ + return -1; + } + + switch(buf[0]){ + case '2': + strcpy(receive,"ARFCN "); + break; + case '3': + strcpy(receive,"UARFCN "); + break; + default: + strcpy(receive,"ERROR"); + return 0; + } + + if(cut_string(buf, ",", ",")!=0){ + return -1; + } + strcat(receive,buf); + return 0; +} + +int ehs5_data_type(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rAT^SIND=\"psinfo\",2\r","OK")!=0){ + return -1; + } + if(cut_string(receive, "SIND: psinfo,", "\r")!=0){ + return -1; + } + if(cut_string(receive, ",","")!=0){ + return -1; + } + + switch(receive[0]){ + case '0': strcpy(receive,"GPRS/EGPRS not available"); break; + //case '1': strcpy(receive,"GPRS available"); break; + case '2': strcpy(receive,"GPRS"); break; + case '3': strcpy(receive,"EGPRS available"); break; + case '4': strcpy(receive,"EGPRS"); break; + case '5': strcpy(receive,"WCDMA camped"); break; + case '6': strcpy(receive,"WCDMA"); break; + case '7': strcpy(receive,"HSDPA camped"); break; + case '8': strcpy(receive,"HSDPA"); break; + case '9': strcpy(receive,"HSDPA/HSUPA camped"); break; + case '1': + if(receive[1]=='0'){ + strcpy(receive,"HSDPA/HSUPA"); + break; + } else { + strcpy(receive,"GPRS available"); + break; + } + default: strcpy(receive,"UNKNOWN"); break; + } + + return 0; +} + +int ehs5_imei(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CGSN\r","OK")!=0){ + return -1; + } + if(cut_string(receive, "AT+CGSN\r\r\n", "\r")!=0){ + return -1; + } + return 0; +} + +int ehs5_power_down(struct settings_entry *settings){ + return 0; +} + +int ehs5_power_up(struct settings_entry *settings){ + return 0; +} + +struct modems_ops ehs5_ops = { + .name = ehs5_name, + .probe = ehs5_probe, + .init = ehs5_init, + .version = ehs5_version, + .imei = ehs5_imei, + .ccid = ehs5_ccid, + .imsi = modem_common_imsi, + .pin_state = modem_common_pin_state, + .csq = modem_common_csq, + .bs_info = ehs5_bs_info, + .registration = modem_common_registration, + .band_info = ehs5_band_info, + .network_type = ehs5_network_type, + .data_registration = modem_common_data_registration, + .operator = modem_common_operator, + .data_type = ehs5_data_type, + .sim_pullout = modem_common_sim_pullout, + .sim_pullup = modem_common_sim_pullup, + .power_down = ehs5_power_down, + .power_up = ehs5_power_up, + .set_mode = modem_common_set_mode, + .set_apn = modem_common_set_apn, + .set_pin = modem_common_set_pin, + .set_auth = modem_common_set_auth +}; diff --git a/simman2/src/modem_sim5300.c b/simman2/src/modem_sim5300.c new file mode 100755 index 00000000..0796d70d --- /dev/null +++ b/simman2/src/modem_sim5300.c @@ -0,0 +1,298 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + +int sim5300_name(char *receive, char *device){ + strcpy(receive,"SIMCOM SIM5300E"); + return 0; +} + +int sim5300_probe(char *device){ + char receive[256]={0}; + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rATI\r","OK")!=0){ + return -1; + } + if(strstr(receive,"SIM5300E")==NULL){ + return -1; + } + + return 0; +} + +int sim5300_init(struct settings_entry *settings){ + char receive[256]={0}; + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + + if(modem_send_command(receive,settings->atdevice,"ATE0\r","OK")!=0){ + return -1; + } + + return 0; +} + +int sim5300_version(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CGMR\r","OK")!=0){ + return -1; + } + if(cut_string(receive, "Revision:", "\r")!=0){ + return -1; + } + return 0; +} + +int sim5300_ccid(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CCID\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "\r\n", "FF\r")!=0){ + strcpy(receive,"ERROR"); + } + return 0; +} + +int sim5300_bs_info(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"AT+CENG=4\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + memset(receive, 0, sizeof(receive)); + + if(modem_send_command(receive,device,"AT+CENG?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(strstr(receive,"UMTS")!=NULL) + { + if(cut_string(receive, "+CENG: 0,\"", "\"")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(common_awk_f(receive,",",5)!=0){ + strcpy(receive,"ERROR"); + } + } else + { + if(cut_string(receive, "+CENG: 0,\"", "\"")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(common_awk_f(receive,",",7)!=0){ + strcpy(receive,"ERROR"); + } + } + + return 0; +} + +int sim5300_network_type(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"AT+CENG=4\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + memset(receive, 0, sizeof(receive)); + + if(modem_send_command(receive,device,"AT+CENG?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(strstr(receive,"UMTS")!=NULL) + { + strcpy(receive,"UMTS"); + + } else + { + strcpy(receive,"GSM"); + + } + + return 0; +} + +int sim5300_band_info(char *receive, char *device){ + char buf[256]={0}; + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(buf,device,"AT+CENG=4\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + memset(buf, 0, sizeof(buf)); + + if(modem_send_command(buf,device,"AT+CENG?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(strstr(buf,"UMTS")!=NULL) + { + strcpy(receive,"UARFCN "); + } else + { + strcpy(receive,"ARFCN "); + } + + if(cut_string(buf, "+CENG: 0,\"", "\"")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(common_awk_f(buf,",",1)!=0){ + strcpy(buf,"ERROR"); + } + + strcat(receive,buf); + return 0; +} + + +int sim5300_data_type(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CSACT?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "+CSACT: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(common_awk_f(receive,",",1)!=0){ + strcpy(receive,"ERROR"); + } + + switch(receive[0]){ + case '0': strcpy(receive,"GSM"); break; + case '1': strcpy(receive,"GPRS"); break; + case '2': strcpy(receive,"WCDMA"); break; + case '3': strcpy(receive,"EGPRS (EDGE)"); break; + case '4': strcpy(receive,"HSDPA only (WCDMA)"); break; + case '5': strcpy(receive,"HSUPA only (WCDMA)"); break; + case '6': strcpy(receive,"HSPA (HSDPA and HSUPA, WCDMA)"); break; + case '7': strcpy(receive,"LTE"); break; + default: strcpy(receive,"UNKNOWN"); break; + } + + return 0; +} + +int sim5300_imei(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CGSN\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "\r\n", "\r\n")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + return 0; +} + +int sim5300_sim_pullout(struct settings_entry *settings){ + char buf[256]={0}; + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + + if(modem_send_command(buf,settings->atdevice,"\rAT+CFUN=0\r","OK")!=0){ + return -1; + } + + return 0; +} + +int sim5300_sim_pullup(struct settings_entry *settings){ + char buf[256]={0}; + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + + if(modem_send_command(buf,settings->atdevice,"\rAT+CFUN=1\r","OK")!=0){ + return -1; + } + + return 0; +} + +int sim5300_power_down(struct settings_entry *settings){ + return 0; +} + +int sim5300_power_up(struct settings_entry *settings){ + return 0; +} + +struct modems_ops sim5300_ops = { + .name = sim5300_name, + .init = sim5300_init, + .probe = sim5300_probe, + .version = sim5300_version, + .imei = sim5300_imei, + .ccid = sim5300_ccid, + .imsi = modem_common_imsi, + .pin_state = modem_common_pin_state, + .csq = modem_common_csq, + .bs_info = sim5300_bs_info, + .registration = modem_common_registration, + .band_info = sim5300_band_info, + .network_type = sim5300_network_type, + .data_registration = modem_common_data_registration, + .operator = modem_common_operator, + .data_type = sim5300_data_type, + .sim_pullout = sim5300_sim_pullout, + .sim_pullup = sim5300_sim_pullup, + .power_down = sim5300_power_down, + .power_up = sim5300_power_up, + .set_mode = modem_common_set_mode, + .set_apn = modem_common_set_apn, + .set_pin = modem_common_set_pin, + .set_auth = modem_common_set_auth +}; diff --git a/simman2/src/modem_sim5360.c b/simman2/src/modem_sim5360.c new file mode 100755 index 00000000..811558fb --- /dev/null +++ b/simman2/src/modem_sim5360.c @@ -0,0 +1,302 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + +int sim5360_name(char *receive, char *device){ + strcpy(receive,"SIMCOM SIM5360E"); + return 0; +} + +int sim5360_probe(char *device){ + char receive[256]={0}; + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rATI\r","OK")!=0){ + return -1; + } + if(strstr(receive,"SIMCOM_SIM5360E")==NULL){ + return -1; + } + + return 0; +} + +int sim5360_init(struct settings_entry *settings){ + char buf[256]={0}; + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + modem_send_command(buf,settings->atdevice,"\rAT+AUTOANSWER=0,0\r","OK"); + + return 0; +} + +int sim5360_version(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CGMR\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "+CGMR: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + return 0; +} + +int sim5360_ccid(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CICCID\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "+ICCID: ", "\r")!=0){ + strcpy(receive,"ERROR"); + } + return 0; +} + +int sim5360_bs_info(char *receive, char *device){ + uint8_t i; + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CPSI?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "CPSI: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(common_awk_f(receive,",",5)!=0){ + strcpy(receive,"ERROR"); + } + + return 0; +} + +int sim5360_network_type(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CPSI?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "CPSI: ", ",")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + return 0; +} + +int sim5360_band_info(char *receive, char *device){ + char buf[256]={0}; + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(buf,device,"\rAT+CPSI?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(buf, "CPSI: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + switch(buf[0]){ + case 'L': //LTE + if(common_awk_f(buf,",", 8)!=0){ + strcpy(receive,"ERROR"); + return 0; + } + strcpy(receive,"EARFCN "); + break; + case 'W': //WCDMA + if(common_awk_f(buf,",", 8)!=0){ + strcpy(receive,"ERROR"); + return 0; + } + strcpy(receive,"UARFCN "); + break; + case 'G': //GSM + if(common_awk_f(buf,",", 6)!=0){ + strcpy(receive,"ERROR"); + return 0; + } + strcpy(receive,"ARFCN "); + break; + default: + strcpy(receive,"ERROR"); + return 0; + } + + strcat(receive,buf); + return 0; +} + + +int sim5360_data_type(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CNSMOD?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "+CNSMOD: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, ",","")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + switch(receive[0]){ + case '0': strcpy(receive,"No service"); break; + case '1': strcpy(receive,"GSM"); break; + case '2': strcpy(receive,"GPRS"); break; + case '3': strcpy(receive,"EGPRS (EDGE)"); break; + case '4': strcpy(receive,"WCDMA"); break; + case '5': strcpy(receive,"HSDPA only (WCDMA)"); break; + case '6': strcpy(receive,"HSUPA only (WCDMA)"); break; + case '7': strcpy(receive,"HSPA (HSDPA and HSUPA, WCDMA)"); break; + case '8': strcpy(receive,"LTE"); break; + default: strcpy(receive,"UNKNOWN"); break; + } + + return 0; +} + +int sim5360_imei(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CGSN\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "AT+CGSN\r\r\n", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + return 0; +} + +int sim5360_power_down(struct settings_entry *settings){ + char buf[256]={0}; + char count=0; + + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + modem_send_command(buf,settings->atdevice,"\rAT+CPOF\r","OK"); + + while(count<=30) + { + if(modem_common_exist(settings->atdevice)==-1){ + break; + } + count++; + sleep(1); + } + + if(count==30){ + return -1; + } + gpio_set_value(settings->gsmpow_pin,HIGH); + sleep(1); + + return 0; +} + +int sim5360_power_up(struct settings_entry *settings){ + uint8_t count=0; + gpio_set_value(settings->pwrkey_pin,HIGH); + usleep(500); + gpio_set_value(settings->gsmpow_pin,LOW); + while(count<=45){ + count++; + if(modem_common_exist(settings->atdevice)==0){ + return 0; + } + sleep(1); + } + if(count==45){ + return -1; + } + + return 0; +} + +int sim5360_sim_pullout(struct settings_entry *settings){ + if(sim5360_power_down(settings)!=0){ + return -1; + } + return 0; +} + +int sim5360_sim_pullup(struct settings_entry *settings){ + if(sim5360_power_up(settings)!=0){ + return -1; + } + return 0; +} + +struct modems_ops sim5360_ops = { + .name = sim5360_name, + .init = sim5360_init, + .probe = sim5360_probe, + .version = sim5360_version, + .imei = sim5360_imei, + .ccid = sim5360_ccid, + .imsi = modem_common_imsi, + .pin_state = modem_common_pin_state, + .csq = modem_common_csq, + .bs_info = sim5360_bs_info, + .registration = modem_common_registration, + .band_info = sim5360_band_info, + .network_type = sim5360_network_type, + .data_registration = modem_common_data_registration, + .operator = modem_common_operator, + .data_type = sim5360_data_type, + .sim_pullout = sim5360_sim_pullout, + .sim_pullup = sim5360_sim_pullup, + .power_down = sim5360_power_down, + .power_up = sim5360_power_up, + .set_mode = modem_common_set_mode, + .set_apn = modem_common_set_apn, + .set_pin = modem_common_set_pin, + .set_auth = modem_common_set_auth +}; diff --git a/simman2/src/modem_sim7600.c b/simman2/src/modem_sim7600.c new file mode 100755 index 00000000..d97abc73 --- /dev/null +++ b/simman2/src/modem_sim7600.c @@ -0,0 +1,374 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "common.h" + +int sim7600_name(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rATI\r","OK")!=0){ + return -1; + } + if(strstr(receive,"SIMCOM_SIM7100E")!=NULL){ + strcpy(receive,"SIMCOM SIM7100E"); + return 0; + } + if(strstr(receive,"SIMCOM_SIM7600E")!=NULL){ + strcpy(receive,"SIMCOM SIM7600E-H"); + return 0; + } + strcpy(receive,"ERROR"); + return -1; +} + +int sim7600_probe(char *device){ + char receive[256]={0}; + if(modem_common_send_at(device)!=0){ + return -1; + } + + if(modem_send_command(receive,device,"\rATI\r","OK")!=0){ + return -1; + } + if(strstr(receive,"SIMCOM_SIM7100E")==NULL && strstr(receive,"SIMCOM_SIM7600E")==NULL){ + return -1; + } + + return 0; +} + +int sim7600_init(struct settings_entry *settings){ + char buf[256]={0}; + uint8_t reset=0; + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + + if(modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPON?\r","OK")!=0) + { + return -1; + } + + if(strstr(buf,"+UIMHOTSWAPON: 1")==NULL) + { + modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPON=1\r","OK"); + reset=1; + } + + memset(buf,0,sizeof(buf)); + + modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPLEVEL?\r","OK"); + if(strstr(buf,"+UIMHOTSWAPLEVEL: 1")==NULL) + { + modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPLEVEL=1\r","OK"); + reset=1; + } + + if(reset) + { + modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPON=1\r","OK"); + modem_send_command(buf,settings->atdevice,"\rAT+UIMHOTSWAPLEVEL=1\r","OK"); + sim7600_power_down(settings); + sim7600_power_up(settings); + } + + return 0; +} + +int sim7600_version(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CGMR\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "+CGMR: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + return 0; +} + +int sim7600_ccid(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CICCID\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "+ICCID: ", "\r")!=0){ + strcpy(receive,"ERROR"); + } + return 0; +} + +int sim7600_bs_info(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CPSI?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "CPSI: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(common_awk_f(receive,",",5)!=0){ + strcpy(receive,"ERROR"); + } + + return 0; +} + +int sim7600_network_type(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CPSI?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "CPSI: ", ",")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + return 0; +} + +int sim7600_operator(char *receive, char *device){ + char operator[128]; + char mcc[128]; + + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(operator,device,"\rAT+COPS?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(cut_string(operator, "\"", "\",")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + cut_string(operator, "", " "); + + if(modem_send_command(mcc,device,"\rAT+CPSI?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(cut_string(mcc, "Online,", ",")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + for (int i = 0; i < strlen(mcc); i++) { + if (mcc[i] == '-') { + memmove(&mcc[i], &mcc[i+1], strlen(mcc) - i - 1); + mcc[strlen(mcc)-1]='\0'; + break; + } + } + + sprintf(receive,"%s (%s)",operator,mcc); + return 0; +} + +int sim7600_band_info(char *receive, char *device){ + char buf[256]={0}; + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(buf,device,"\rAT+CPSI?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(buf, "CPSI: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + switch(buf[0]){ + case 'L': //LTE + if(common_awk_f(buf,",", 8)!=0){ + strcpy(receive,"ERROR"); + return 0; + } + strcpy(receive,"EARFCN "); + break; + case 'W': //WCDMA + if(common_awk_f(buf,",", 8)!=0){ + strcpy(receive,"ERROR"); + return 0; + } + strcpy(receive,"UARFCN "); + break; + case 'G': //GSM + if(common_awk_f(buf,",", 6)!=0){ + strcpy(receive,"ERROR"); + return 0; + } + strcpy(receive,"ARFCN "); + break; + default: + strcpy(receive,"ERROR"); + return 0; + } + + strcat(receive,buf); + return 0; +} + + +int sim7600_data_type(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CNSMOD?\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "+CNSMOD: ", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, ",","")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + switch(receive[0]){ + case '0': strcpy(receive,"No service"); break; + case '1': strcpy(receive,"GSM"); break; + case '2': strcpy(receive,"GPRS"); break; + case '3': strcpy(receive,"EGPRS (EDGE)"); break; + case '4': strcpy(receive,"WCDMA"); break; + case '5': strcpy(receive,"HSDPA only (WCDMA)"); break; + case '6': strcpy(receive,"HSUPA only (WCDMA)"); break; + case '7': strcpy(receive,"HSPA (HSDPA and HSUPA, WCDMA)"); break; + case '8': strcpy(receive,"LTE"); break; + default: strcpy(receive,"UNKNOWN"); break; + } + + return 0; +} + +int sim7600_imei(char *receive, char *device){ + if(modem_common_send_at(device)!=0){ + strcpy(receive,"ERROR"); + return -1; + } + + if(modem_send_command(receive,device,"\rAT+CGSN\r","OK")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + if(cut_string(receive, "AT+CGSN\r\r\n", "\r")!=0){ + strcpy(receive,"ERROR"); + return -1; + } + return 0; +} + +int sim7600_power_down(struct settings_entry *settings){ + char buf[256]={0}; + char count=0; + + ubus_interface_down(settings->iface); + if(modem_common_send_at(settings->atdevice)!=0){ + return -1; + } + modem_send_command(buf,settings->atdevice,"\rAT+CPOF\r","OK"); + + while(count<=30) + { + if(modem_common_exist(settings->atdevice)==-1){ + break; + } + count++; + sleep(1); + } + + if(count==30){ + return -1; + } + gpio_set_value(settings->gsmpow_pin,HIGH); + sleep(1); + + return 0; +} + +int sim7600_power_up(struct settings_entry *settings){ + uint8_t count=0; + gpio_set_value(settings->pwrkey_pin,HIGH); + usleep(500); + gpio_set_value(settings->gsmpow_pin,LOW); + while(count<=45){ + count++; + if(modem_common_exist(settings->atdevice)==0){ + return 0; + } + sleep(1); + } + if(count==45){ + return -1; + } + + return 0; +} + +struct modems_ops sim7600_ops = { + .name = sim7600_name, + .init = sim7600_init, + .probe = sim7600_probe, + .version = sim7600_version, + .imei = sim7600_imei, + .ccid = sim7600_ccid, + .imsi = modem_common_imsi, + .pin_state = modem_common_pin_state, + .csq = modem_common_csq, + .bs_info = sim7600_bs_info, + .registration = modem_common_registration, + .band_info = sim7600_band_info, + .network_type = sim7600_network_type, + .data_registration = modem_common_data_registration, + .operator = sim7600_operator, + .data_type = sim7600_data_type, + .sim_pullout = modem_common_sim_pullout, + .sim_pullup = modem_common_sim_pullup, + .power_down = sim7600_power_down, + .power_up = sim7600_power_up, + .set_mode = modem_common_set_mode, + .set_apn = modem_common_set_apn, + .set_pin = modem_common_set_pin, + .set_auth = modem_common_set_auth +}; diff --git a/simman2/src/simman.c b/simman2/src/simman.c new file mode 100755 index 00000000..b2295c4d --- /dev/null +++ b/simman2/src/simman.c @@ -0,0 +1,515 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SYSLOG_NAMES +#include + +#include "common.h" + + +enum { + INIT = 0, + MODEM_INIT, + IDLE, + GET_CCID, + GET_IMEI, + CH_SIM, +}; + +int sim1_status=-1, // SIM1 status, 0 - detect, 1 - not detect, -1 - unknown + sim2_status=-1, // SIM2 status + first_start, + active_sim; // active SIM, 0 - SIM1, 1 - SIM2, -1 - unknown + +uint8_t state, + changeCounter, + changeCounterForReboot, + retry; + +static const char *config; + +static int display_usage(void) +{ + printf("Options:\n" + " -c CONFIG: Run program with the requested CONFIG\n" + ); + exit(EXIT_FAILURE); +} + +int ModemStarted(char *atdevice) +{ + // 0 - OK, -1 - not found + return access(atdevice, F_OK); +} + +int ModemReset(struct settings_entry *settings, struct modems_ops *modem) +{ + return (modem_common_power_reset(settings,modem)); +} + +int SetSim(struct settings_entry *settings, struct modems_ops *modem, uint8_t sim) +{ + changeCounterForReboot++; + changeCounter++; + //LOG("changeCounter now %d and changeCounterForReboot %d \n", changeCounter, changeCounterForReboot); + if(settings->sw_before_sysres != 0) + { + if(changeCounterForReboot > settings->sw_before_sysres) + { + LOG("Sim switched %d times\n", changeCounterForReboot); + LOG("Reboot...\n"); + sync(); + reboot(RB_AUTOBOOT); + } + } + + if(settings->sw_before_modres != 0) + { + if(changeCounter > settings->sw_before_modres) + { + LOG("Sim switched %d times\n", changeCounter); + LOG("Modem reset...\n"); + + modem_common_power_reset(settings,modem); + changeCounter = 0; + changeCounterForReboot--; + first_start = 1; + return 0; + } + + } + + if ((settings->only_first_sim == 0) || (first_start == 1)) + { + switch_sim(settings, modem, sim, first_start); + first_start = 0; + + } + else + { + LOG("switching to over SIM is not necessary\n"); + switch_sim(settings, modem, (sim==0)?1:0, first_start); + } + + if(changeCounter>101) + changeCounter=0; + if(changeCounterForReboot>101) + changeCounterForReboot=0; + + return 0; +} + +int chartoint(char *s) +{ + int i, n=0; + for(i=0; isdigit(s[i]); ++i){ + n=10*n+(s[i]-'0'); + } + return n; +} + +int main(int argc, char **argv) +{ + struct settings_entry settings; + int ch, ret = 0; + int i, + tmp, + ch_sim, + num_sim, + sig_level, + hot_change; + + time_t now_time, prev_time, prev_delay_time; + double diff, diff_delay; + + struct modems_ops *modem = NULL; + + signal(SIGPIPE, SIG_IGN); + + while ((ch = getopt(argc, argv, "hc:")) != -1) { + switch (ch) { + case 'c': + config=optarg; + break; + case 'h': + default: + return display_usage(); + } + } + + if (!config) { + LOG("No config given\n"); + display_usage(); + } + + time(&now_time); + prev_time = prev_delay_time = now_time; + + state = INIT; + first_start = 1; + hot_change = 1; + ch_sim = 0; + changeCounter = 0; + changeCounterForReboot = 0; + + LOG("service started\n"); + + if (uci_read_configuration(&settings,config) == 0) + do{ + // get now time + time(&now_time); + // in seconds + diff = difftime(now_time, prev_time); + diff_delay = difftime(now_time, prev_delay_time); + + // check if modem exists + if (first_start && ModemStarted(settings.atdevice) < 0 ) + { + LOG("waiting for modem to turn on\n"); + for(int i=0; i<30; i++){ + sleep(1); + if(ModemStarted(settings.atdevice) >= 0) + break; + } + } + + if ( ModemStarted(settings.atdevice) < 0 ) + { + LOG("modem not found, try to turn on\n"); + state = MODEM_INIT; + } + else + if (state == INIT) + { + modem = modems_backend(settings.atdevice); + if(modem!=NULL) + { + LOG("modem started\n"); + modem->init(&settings); + state = GET_IMEI; + first_start = 1; + } else + { + LOG("modem does not respond to AT-commands\n"); + ModemReset(&settings,modem); + state = INIT; + } + } + + // read num active SIM card + active_sim = gpio_read(settings.simaddr_pin); + + // check SIM1 status + tmp = gpio_read(settings.simdet0_pin); + if ((tmp >= 0) && (tmp != sim1_status) && !first_start) + { // SIM1 remove + if (((tmp == 1)&&(active_sim == 0)) // вытянули сим 1 + ||((tmp == 0)&&(settings.sim[0].prio > settings.sim[1].prio)) // вставили сим 1 и приоритет у нее выше + ||((tmp == 0)&&(sim2_status != 0))) // вытащили сим 2 и приоритет у нее выше + { + for (i = 0; i < sizeof(settings.serv)/sizeof(settings.serv[0]); i++) + { + settings.serv[i].retry_check = 0; + } + hot_change = 1; + state = CH_SIM; + } + } + sim1_status = tmp; + + // check SIM2 status + tmp = gpio_read(settings.simdet1_pin); + if ((tmp >= 0) && (tmp != sim2_status) && !first_start) + { // SIM2 remove + if (((tmp == 1)&&(active_sim > 0)) // вытянули сим 2 + ||((tmp == 0)&&(settings.sim[0].prio < settings.sim[1].prio)) // вставили сим 2 и приоритет у нее выше + ||((tmp == 0)&&(sim1_status != 0))) // вытащили сим 1 и приоритет у нее выше + { + for (i = 0; i < sizeof(settings.serv)/sizeof(settings.serv[0]); i++) + { + settings.serv[i].retry_check = 0; + } + hot_change = 1; + state = CH_SIM; + } + } + sim2_status = tmp; + + if (first_start && (state == GET_IMEI || state == GET_CCID )) + { + if (settings.sim[0].prio < settings.sim[1].prio) + { + if (active_sim == 0) + { + if (sim2_status==0) //если SIM2 обнаружена + { + SetSim(&settings,modem,1); + LOG("SIM2 has the highest priority\n"); + } + else + { + LOG("SIM2 is not available\n"); + SetSim(&settings,modem,0); + } + } + else + { + if (active_sim == 1) + { + if ((sim2_status != 0)&&(sim1_status == 0)) + { + LOG("Only SIM1 detected\n"); + SetSim(&settings,modem,0); + } + else + { + LOG("SIM2 is active\n"); + SetSim(&settings,modem,active_sim); + } + } + else + LOG("No one SIM is available\n"); + } + } + else + { + if (active_sim == 1) + { + if (sim1_status==0) //Если SIM1 обнаружена + { + SetSim(&settings,modem,0); + LOG("SIM1 has the highest priority\n"); + } + else + { + LOG("SIM1 is not available\n"); + SetSim(&settings,modem,1); + } + } + else + { + if (active_sim == 0) + { + if ((sim1_status != 0)&&(sim2_status == 0)) + { + LOG("Only SIM2 detected\n"); + SetSim(&settings,modem,1); + } + else + { + LOG("SIM1 is active\n"); + SetSim(&settings,modem,active_sim); + } + } + else + LOG("No one SIM is available\n"); + } + } + active_sim = gpio_read(settings.simaddr_pin); + first_start = 0; + hot_change = 0; + } + first_start = hot_change; + hot_change = 0; + + if (((active_sim == 0 ) && (settings.sim[0].prio < settings.sim[1].prio)) + ||((active_sim > 0) && (settings.sim[0].prio > settings.sim[1].prio))) + { + if ( diff_delay >= settings.delay ) + { + prev_delay_time = now_time; + ch_sim = 1; + + LOG("attempt to switch to the priority SIM (act.SIM%d p1/p2=%d/%d)\n", + active_sim+1, + settings.sim[0].prio, + settings.sim[1].prio); + } + } + else + { + prev_delay_time = now_time; + } + + + fprintf(stderr,"%.0f %d %d %d\n", diff, sim1_status, sim2_status, active_sim); + + switch(state) + { + case MODEM_INIT: + if(ModemReset(&settings,modem)==0) + { + state = INIT; + } + break; + case INIT: break; + case GET_IMEI: + // get modem IMEI + settings.imei = modem_summary(modem,INFO_IMEI, settings.atdevice); + + prev_time = now_time; + + if (strstr(settings.imei,"NONE") != NULL) + { + if (++retry >= 2 ) + state = IDLE; + else + LOG("retry #%d reading IMEI\n", retry+1); + break; + } + LOG("found modem with IMEI %s\n",settings.imei); + state = GET_CCID; + break; + case GET_CCID: + if ( (long int)diff >= 3) + { + settings.ccid = modem_summary(modem,INFO_CCID, settings.atdevice); + + prev_time = now_time; + + if (strstr(settings.ccid,"NONE") != NULL || strstr(settings.ccid,"ERR") != NULL) + { + if (++retry >= 2 ) + state = IDLE; + else + LOG("retry #%d reading CCID\n", retry+1); + break; + } + LOG("act. SIM%d with CCID %s\n", active_sim+1, settings.ccid); + state = IDLE; + } + break; + case IDLE: + if (ch_sim) + { // if need change SIM card + ch_sim = 0; + state = CH_SIM; + break; + } + + if (diff < settings.check_period && diff >= 0) + break; + + if (settings.csq_level != 0){ + sig_level = chartoint(modem_summary(modem,INFO_SIGLEV, settings.atdevice)); + if (sig_level == 99) { + sleep(1); + sig_level = chartoint(modem_summary(modem,INFO_SIGLEV, settings.atdevice)); + } + LOG("Current ASU: %d\n", sig_level); + if (sig_level < settings.csq_level || sig_level == 99) + LOG("ASU not detectable or below specified: %d ASU (min: %d ASU)\n", sig_level, settings.csq_level); + } + + LOG("check servers\n"); + + uint8_t need_change_sim = 0; + + for (i = 0; i < sizeof(settings.serv)/sizeof(settings.serv[0]); i++) + { + if (!settings.serv[i].ip) + break; + if (settings.serv[i].sim_num == 2 || settings.serv[i].sim_num == active_sim) { + int ack, cnt = 0; + do{ + ack = ping((char*)settings.serv[i].ip, (char*)settings.iface); + //ack = ping((char*)settings.serv[i].ip); + }while(!ack && (++cnt < 3)); + + if (!ack) + settings.serv[i].retry_check++; + else if (settings.csq_level != 0 && (sig_level < settings.csq_level || sig_level == 99)) + settings.serv[i].retry_check++; + else + { + settings.serv[i].retry_check = 0; + changeCounter = 0; + changeCounterForReboot = 0; + } + + if (settings.serv[i].retry_check >= settings.retry_num) + need_change_sim++; + + if (ack) + { + if (settings.csq_level != 0 && (sig_level < settings.csq_level || sig_level == 99)) + LOG("%s - LIVE; ASU LOW (%d/%d)\n", settings.serv[i].ip,settings.serv[i].retry_check, settings.retry_num); + else + LOG("%s - LIVE\n", settings.serv[i].ip); + } + else + LOG("%s - DOWN (%d/%d)\n", settings.serv[i].ip,settings.serv[i].retry_check, settings.retry_num); + } + else + need_change_sim++; + } + + prev_time = now_time; + + if (i == need_change_sim) + { + ch_sim = 1; + + // clear + for (i = 0; i < sizeof(settings.serv)/sizeof(settings.serv[0]); i++) + { + if (!settings.serv[i].ip) + break; + + settings.serv[i].retry_check = 0; + } + } + break; + case CH_SIM: + // need change SIM card + if (active_sim >= 0) + { + num_sim = active_sim; + if (active_sim == 0) + { + if (sim2_status == 0) + { + num_sim = 1; + LOG("attempt to switch to SIM%d\n", num_sim+1); + } + } + else + { + if (sim1_status == 0) + { + num_sim = 0; + LOG("attempt to switch to SIM%d\n", num_sim+1); + } + } + + SetSim(&settings,modem,num_sim); + } + + prev_time = now_time; + retry = 0; + + state = GET_CCID; + break; + default: + state = INIT; + break; + } + // ~0.3 sec + usleep(300000); + }while(1); + + LOG("service stopped\n"); + + return 0; +} + diff --git a/simman2/src/simman_cli.c b/simman2/src/simman_cli.c new file mode 100755 index 00000000..3d0652bd --- /dev/null +++ b/simman2/src/simman_cli.c @@ -0,0 +1,258 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +static const char *device, *config; + +int ModemStarted(char *atdevice) +{ + // 0 - OK, -1 - not found + return access(atdevice, F_OK); +} + +char *GetSimInfo(struct settings_entry *settings) +{ + char b[64] = {0}; + modem_sim_state(b,settings); + return strdup(b); +} + +int GetAllInfo(struct settings_entry *settings) +{ + char cmd[256]; + struct modems_ops *modem = NULL; + modem = modems_backend(settings->atdevice); + if(modem!=NULL){ + fprintf(stdout, "{\n"); + fprintf(stdout, " \"modem\": \"%s\",\n", modem_summary(modem,INFO_MODEM, settings->atdevice)); + fprintf(stdout, " \"firmware\": \"%s\",\n", modem_summary(modem,INFO_FW, settings->atdevice)); + fprintf(stdout, " \"imei\": \"%s\",\n", modem_summary(modem,INFO_IMEI, settings->atdevice)); + fprintf(stdout, " \"ccid\": \"%s\",\n", modem_summary(modem,INFO_CCID, settings->atdevice)); + fprintf(stdout, " \"imsi\": \"%s\",\n", modem_summary(modem,INFO_IMSI, settings->atdevice)); + fprintf(stdout, " \"sim_state\": \"%s\",\n", GetSimInfo(settings)); + fprintf(stdout, " \"pin_state\": \"%s\",\n", modem_summary(modem,INFO_PINSTAT, settings->atdevice)); + fprintf(stdout, " \"operator\": \"%s\",\n", modem_summary(modem,INFO_OP, settings->atdevice)); + fprintf(stdout, " \"csq\": \"%s\",\n", modem_summary(modem,INFO_SIGLEV, settings->atdevice)); + fprintf(stdout, " \"net_reg\": \"%s\",\n", modem_summary(modem,INFO_REGSTAT, settings->atdevice)); + fprintf(stdout, " \"net_type\": \"%s\",\n", modem_summary(modem,INFO_NETTYPE, settings->atdevice)); + fprintf(stdout, " \"data_reg\": \"%s\",\n", modem_summary(modem,INFO_GPRSSTAT, settings->atdevice)); + fprintf(stdout, " \"data_type\": \"%s\",\n", modem_summary(modem,INFO_PACKTYPE, settings->atdevice)); + fprintf(stdout, " \"bs_id\": \"%s\",\n", modem_summary(modem,INFO_BASESTID, settings->atdevice)); + fprintf(stdout, " \"band\": \"%s\"\n", modem_summary(modem,INFO_BASESTBW, settings->atdevice)); + fprintf(stdout, "}\n"); + } else + { + LOG("modem does not respond to AT-commands or unknown modem\n"); + } + return 0; +} + +static const char *optString = "d:a:s:x:o:cprbnimfRBSDIPh?"; +static const struct option longOpts[] = { + {"device",required_argument, NULL,'d'}, + {"get-sim",required_argument, NULL,'s' }, + {"get-ccid",no_argument, NULL,'c'}, + {"get-pin-status",no_argument, NULL,'p'}, + {"get-rssi",no_argument, NULL,'r'}, + {"get-reg",no_argument, NULL,'R'}, + {"get-bsid",no_argument, NULL,'B'}, + {"get-band",no_argument, NULL,'b'}, + {"get-net-type",no_argument, NULL,'n'}, + {"get-data-status",no_argument, NULL,'S'}, + {"get-data-type",no_argument, NULL,'D'}, + {"get-imsi",no_argument, NULL,'i'}, + {"get-imei",no_argument, NULL,'I'}, + {"get-modem",no_argument, NULL,'m'}, + {"get-fw",no_argument, NULL,'f'}, + {"get-plmn",no_argument, NULL,'P'}, + {"all",required_argument, NULL,'a'}, + {"power-off",required_argument, NULL,'x'}, + {"power-up",required_argument, NULL,'o'}, + {"help", no_argument, NULL,'h'}, + { NULL, no_argument, NULL, 0 } +}; + +void display_usage(void) +{ + printf("Usage: simman2_cli -d [PORT] [-cprRBbnSDiImf]\n" + " or simman2_cli [-asxo[CONFIG]]\n" + "Options:\n" + " --device=PORT, -d PORT: Set device name to PORT\n" + " --get-ccid, -c: Get CCID SIM card\n" + " --get-pin-status, -p: Get PIN status\n" + " --get-rssi, -r: Get RSSI level\n" + " --get-reg, -R: Get registration status\n" + " --get-bsid, -B: Get base station id\n" + " --get-band, -b: Get mobile band\n" + " --get-net-type, -n: Get network type\n" + " --get-data-status, -S: Get data connection status\n" + " --get-data-type, -D: Get data connection type\n" + " --get-imsi, -i: Get IMSI SIM card\n" + " --get-imei, -I: Get IMEI modem\n" + " --get-modem, -m: Get modem type\n" + " --get-fw, -f: Get firmware version\n" + " --get-plmn, -P: Get currently selected operator\n" + " OR\n" + " --all=CONFIG, -a CONFIG: Get all information about the requested CONFIG\n" + " --get-sim=CONFIG, -s CONFIG: Get SIM information\n" + " --power-off=CONFIG, -x CONFIG: Modem shutdown\n" + " --power-up=CONFIG, -o CONFIG: Modem power up\n" + ); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + int ch,cmd; + struct modems_ops *modem = NULL; + + while((ch = getopt_long(argc, argv, optString, longOpts, NULL)) != -1) { + switch(ch){ + case 'd': + device=optarg; + break; + case 's': + cmd=INFO_SIM; + config=optarg; + break; + case 'c': + cmd=INFO_CCID; + break; + case 'p': + cmd=INFO_PINSTAT; + break; + case 'r': + cmd=INFO_SIGLEV; + break; + case 'R': + cmd=INFO_REGSTAT; + break; + case 'B': + cmd=INFO_BASESTID; + break; + case 'b': + cmd=INFO_BASESTBW; + break; + case 'n': + cmd=INFO_NETTYPE; + break; + case 'S': + cmd=INFO_GPRSSTAT; + break; + case 'D': + cmd=INFO_PACKTYPE; + break; + case 'i': + cmd=INFO_IMSI; + break; + case 'I': + cmd=INFO_IMEI; + break; + case 'm': + cmd=INFO_MODEM; + break; + case 'f': + cmd=INFO_FW; + break; + case 'P': + cmd=INFO_OP; + break; + case 'a': + cmd=INFO_ALL; + config=optarg; + break; + case 'x': + cmd=POWER_OFF; + config=optarg; + break; + case 'o': + cmd=POWER_UP; + config=optarg; + break; + case 'h': + case '?': + default: + display_usage(); + break; + } + } + if ((!device) && (!config)) { + LOG("No device or config given\n"); + display_usage(); + } + if (!config) { + if ( ModemStarted(device) < 0 ) + { + LOG("Modem not found\n"); + return 1; + } + + modem = modems_backend(device); + if(modem!=NULL && cmd!=NULL){ + fprintf(stdout, "%s\n", modem_summary(modem,cmd,device)); + } else + { + LOG("modem does not respond to AT-commands or unknown modem\n"); + } + } else { + struct settings_entry settings; + if (uci_read_configuration(&settings,config)==0) + { + if(cmd==INFO_SIM){ + fprintf(stdout, "%s\n", GetSimInfo(&settings)); + return 0; + } + + if(cmd==INFO_ALL) { + if(ModemStarted(settings.atdevice) < 0 ) { + LOG("modem not found\n"); + return 1; + } + if(GetAllInfo(&settings)) { + LOG("Error while reading SIM info\n"); + return 1; + } + return 0; + } + + if(ModemStarted(settings.atdevice) < 0) { + if(cmd==POWER_UP) { + LOG("modem power up\n"); + modem_common_power_up(&settings,NULL); + return 0; + } + if(cmd==POWER_OFF) { + LOG("modem powered off\n"); + return 0; + } + } else { + modem = modems_backend(settings.atdevice); + if(modem!=NULL) { + if(cmd==POWER_UP) { + LOG("modem powered on\n"); + return 0; + } + if(cmd==POWER_OFF) { + LOG("modem power off\n"); + modem->power_down(&settings); + return 0; + } + } else { + LOG("modem does not respond to AT-commands or unknown modem\n"); + return 1; + } + } + } + } + return 0; +} diff --git a/smscontrol/Makefile b/smscontrol/Makefile new file mode 100755 index 00000000..c6292a5b --- /dev/null +++ b/smscontrol/Makefile @@ -0,0 +1,41 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=smscontrol +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/smscontrol + +include $(INCLUDE_DIR)/package.mk + +define Package/smscontrol + SECTION:=utils + CATEGORY:=Utilities + TITLE:=CLI commands over sms and calls + DEPENDS:=smstools3-fix + PKGARCH:=all +endef + +define Package/smscontrol/description + Utility to send CLI commands over sms and calls +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/smscontrol/install + $(INSTALL_DIR) $(1)/etc/smscontrol + $(CP) ./files/smshandler $(1)/etc/smscontrol/smshandler + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/smscontrol.config $(1)/etc/config/smscontrol + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/smscontrol.init $(1)/etc/init.d/smscontrol +endef + +$(eval $(call BuildPackage,smscontrol)) diff --git a/smscontrol/files/smscontrol.config b/smscontrol/files/smscontrol.config new file mode 100644 index 00000000..3d4f0334 --- /dev/null +++ b/smscontrol/files/smscontrol.config @@ -0,0 +1,26 @@ +config smscontrol 'common' + option enabled '0' + +config smscontrol 'send' + option to '' + option msgtxt '' + +config call + option enabled '0' + option ack '0' + option command 'reboot' + +config remote + option enabled '0' + option received 'reboot' + option command 'reboot' + +config remote + option enabled '0' + option received 'factory' + option command 'firstboot -y && reboot' + +config cli + option enabled '0' + option received 'CLI$any_cli_command_here' + option command 'any_cli_command_here' diff --git a/smscontrol/files/smscontrol.init b/smscontrol/files/smscontrol.init new file mode 100755 index 00000000..dbff517b --- /dev/null +++ b/smscontrol/files/smscontrol.init @@ -0,0 +1,140 @@ +#!/bin/sh /etc/rc.common + +START=90 +USE_PROCD=1 + +DIR="/var/spool/smscontrol" +COMMANDS="/var/spool/smscontrol/commands" +CALLS="/var/spool/smscontrol/calls" +CLI="/var/spool/smscontrol/cli" +OUT_DIR="/var/spool/sms/outgoing" + +generate_pass() { + config_get PASS common pass + if [ -z "$PASS" ]; then + . /usr/share/libubox/jshn.sh + json_load "$(ubus call system board)" + json_get_var MODEL model + case "$MODEL" in + "TELEOFIS LT70") + PASS=$(head -c 1000 /dev/urandom | tr -dc '0-9' | cut -c -8) + ;; + "TELEOFIS RTUx68" | "TELEOFIS RTUx68 RE-DE") + PASS=$(getserialnum) + ;; + esac + uci_set smscontrol common pass "$PASS" + uci_commit smscontrol + fi +} + +add_comm() { + config_get enabled "$1" "enabled" + [ "$enabled" = "0" ] && continue + + config_get ack "$1" "ack" + config_get received "$1" "received" + config_get command "$1" "command" + + echo " \"$received\")" >> "$COMMANDS" + + if [ "$ack" = "1" ]; then + echo " REPLY=\$($command)" >> "$COMMANDS" + echo " if [ -n \"\$REPLY\" ]; then" >> "$COMMANDS" + echo " DATE=\$(date +%s)" >> "$COMMANDS" + echo " touch /tmp/sms\$DATE.sms" >> "$COMMANDS" + echo " echo \"To: \$2\" >> /tmp/sms\$DATE.sms" >> "$COMMANDS" + echo " echo \"\" >> /tmp/sms\$DATE.sms" >> "$COMMANDS" + echo " echo \"\$REPLY\" >> /tmp/sms\$DATE.sms" >> "$COMMANDS" + echo " cp /tmp/sms\$DATE.sms $OUT_DIR/sms\$DATE.sms" >> "$COMMANDS" + echo " rm /tmp/sms\$DATE.sms" >> "$COMMANDS" + echo " fi" >> "$COMMANDS" + else + echo " $command" >> "$COMMANDS" + fi + echo " ;;" >> "$COMMANDS" + echo " " >> "$COMMANDS" + +} + +add_call() { + config_get enabled "$1" "enabled" + [ "$enabled" = "0" ] && continue + + config_get ack "$1" "ack" + config_get command "$1" "command" + + if [ "$ack" = "1" ]; then + echo " REPLY=\$($command)" >> "$CALLS" + echo " if [ -n \"\$REPLY\" ]; then" >> "$CALLS" + echo " DATE=\$(date +%s)" >> "$CALLS" + echo " touch /tmp/sms\$DATE.sms" >> "$CALLS" + echo " echo \"To: \$1\" >> /tmp/sms\$DATE.sms" >> "$CALLS" + echo " echo \"\" >> /tmp/sms\$DATE.sms" >> "$CALLS" + echo " echo \"\$REPLY\" >> /tmp/sms\$DATE.sms" >> "$CALLS" + echo " cp /tmp/sms\$DATE.sms $OUT_DIR/sms\$DATE.sms" >> "$CALLS" + echo " rm /tmp/sms\$DATE.sms" >> "$CALLS" + echo " fi" >> "$CALLS" + else + echo " $command" >> "$CALLS" + fi +} + +add_cli() { + config_get enabled "$1" "enabled" + [ "$enabled" = "0" ] && continue + + config_get ack "$1" "ack" + if [ "$ack" = "1" ]; then + echo " REPLY=\$(eval \$1)" >> "$CLI" + echo " if [ -n \"\$REPLY\" ]; then" >> "$CLI" + echo " DATE=\$(date +%s)" >> "$CLI" + echo " touch /tmp/sms\$DATE.sms" >> "$CLI" + echo " echo \"To: \$2\" >> /tmp/sms\$DATE.sms" >> "$CLI" + echo " echo \"\" >> /tmp/sms\$DATE.sms" >> "$CLI" + echo " echo \"\$REPLY\" >> /tmp/sms\$DATE.sms" >> "$CLI" + echo " cp /tmp/sms\$DATE.sms $OUT_DIR/sms\$DATE.sms" >> "$CLI" + echo " rm /tmp/sms\$DATE.sms" >> "$CLI" + echo " fi" >> "$CLI" + else + echo " eval \$1" >> "$CLI" + fi +} + +stop_service() { + rm "$COMMANDS" 2>/dev/null + rm "$CALLS" 2>/dev/null + rm "$CLI" 2>/dev/null + /etc/init.d/smstools3 stop +} + +start_service() { + config_load smscontrol + generate_pass + enabled=$(uci get smscontrol.common.enabled) + [ -e "/etc/config/smscontrol_log" ] || touch /etc/config/smscontrol_log + if [ "$enabled" -eq "1" ]; then + mkdir -p "$DIR" + touch "$COMMANDS" + chmod +x "$COMMANDS" + touch "$CALLS" + chmod +x "$CALLS" + touch "$CLI" + chmod +x "$CLI" + config_foreach add_call call + config_foreach add_cli cli + echo "case \"\$1\" in" >> "$COMMANDS" + config_foreach add_comm remote + echo "esac" >> "$COMMANDS" + /etc/init.d/smstools3 start + fi +} + +service_triggers() { + procd_add_reload_trigger "smscontrol" +} + +reload_service() { + stop_service + start_service +} diff --git a/smscontrol/files/smshandler b/smscontrol/files/smshandler new file mode 100755 index 00000000..03d4aa7b --- /dev/null +++ b/smscontrol/files/smshandler @@ -0,0 +1,92 @@ +#!/bin/ash +DIR="/var/spool/smscontrol" +ENABLED=$(uci get smscontrol.common.enabled) + +if [ "$ENABLED" -eq "1" ]; then + case "$1" in + RECEIVED) + PASS=$(uci get smscontrol.common.pass) + [ -z "$PASS" ] && exit + PASSLENGTH=$(echo $PASS | wc -c) + MESSAGE=$(cat "$2") + FROM=$(echo "${MESSAGE}"|grep -e '^From\:'|cut -d' ' -f2) + DATE=$(echo "${MESSAGE}"|grep -e '^Received\:'|cut -d' ' -f2,3) + BODY=$(echo "${MESSAGE}"|sed -e '1,/^$/d') + if [[ "$(uci -q get smscontrol.common.smscontrol_log)" = "1" ]]; then + CFG=$(uci add smscontrol_log event) + uci set smscontrol_log.$CFG.date="${DATE}" + uci set smscontrol_log.$CFG.type=SMS + uci set smscontrol_log.$CFG.from="${FROM}" + uci set smscontrol_log.$CFG.message="${BODY}" + uci commit smscontrol_log + fi + [ "$PASS;" != "${BODY::$PASSLENGTH}" ] && exit + ADMINPHONES=$(uci get smscontrol.common.whitelist) + COUNTPHONES=$(echo $ADMINPHONES | wc -w) + COUNT="0" + while [ "$COUNT" -ne "$COUNTPHONES" ]; do + COUNT=$(($COUNT + 1)) + ADMPH=$(echo $ADMINPHONES | awk -v var=$COUNT -F ' ' '{print $var}') + if [ "$ADMPH" -eq "$FROM" ]; then + BODY=${BODY:$PASSLENGTH} + if [ "${BODY::4}" != "CLI\$" ]; then + $DIR/commands "$BODY" "$FROM" & + break + else + BODY=${BODY:4} + $DIR/cli "$BODY" "$FROM" & + break + fi + fi + done + ;; + + USSD) + ;; + + CALL) + MESSAGE=$(cat "$2") + FROM=$(echo "${MESSAGE}"|grep -e '^From\:'|cut -d' ' -f2) + + if [[ "$(uci -q get smscontrol.common.smscontrol_log)" = "1" ]]; then + CFG=$(uci add smscontrol_log event) + DATE=$(date +"%y-%m-%d %H:%M:%S") + uci set smscontrol_log.$CFG.date="${DATE}" + uci set smscontrol_log.$CFG.type=CALL + uci set smscontrol_log.$CFG.from="${FROM}" + uci commit smscontrol_log + fi + + ADMINPHONES=$(uci get smscontrol.common.whitelist) + COUNTPHONES=$(echo $ADMINPHONES | wc -w) + COUNT="0" + while [ "$COUNT" -ne "$COUNTPHONES" ]; do + COUNT=$(($COUNT + 1)) + ADMPH=$(echo $ADMINPHONES | awk -v var=$COUNT -F ' ' '{print $var}') + if [ "$ADMPH" -eq "$FROM" ]; then + $DIR/calls "$FROM" & + break + fi + done + ;; + + SENT) + if [[ "$(uci -q get smscontrol.common.smscontrol_log)" = "1" ]]; then + MESSAGE=$(cat "$2") + TO=$(echo "${MESSAGE}"|grep -e '^To\:'|cut -d' ' -f2) + BODY=$(echo "${MESSAGE}"|sed -e '1,/^$/d') + CFG=$(uci add smscontrol_log event) + DATE=$(date +"%y-%m-%d %H:%M:%S") + uci set smscontrol_log.$CFG.date="${DATE}" + uci set smscontrol_log.$CFG.type=SMS + uci set smscontrol_log.$CFG.to="${TO}" + uci set smscontrol_log.$CFG.message="${BODY}" + uci commit smscontrol_log + fi + ;; + + *) + ;; + esac + +fi diff --git a/smstools3-fix/Makefile b/smstools3-fix/Makefile new file mode 100644 index 00000000..18fcd883 --- /dev/null +++ b/smstools3-fix/Makefile @@ -0,0 +1,65 @@ +# +# Copyright (C) 2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=smstools3 +PKG_VERSION:=3.1.21 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=http://smstools3.kekekasvi.com/packages/ +PKG_HASH:=skip +PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) + +PKG_MAINTAINER:=Harald Geyer +PKG_LICENSE:=GPL-2.0 +PKG_LICENSE_FILES:=LICENSE + +PKG_BUILD_PARALLEL:=0 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/nls.mk + +define Package/smstools3-fix + SECTION:=utils + CATEGORY:=Utilities + TITLE:=SMS Server Tools 3 + DEPENDS:=$(ICONV_DEPENDS) + URL:=http://smstools3.kekekasvi.com/ +endef + +define Package/smstools3/description + The SMS Server Tools 3 is a SMS Gateway software which can send and receive + short messages through GSM modems and mobile phones. +endef + +TARGET_CFLAGS += -D NUMBER_OF_MODEMS=1 +TARGET_CFLAGS += $(if $(ICONV_FULL),-D USE_ICONV) +TARGET_CFLAGS += -D DISABLE_INET_SOCKET +TARGET_CFLAGS += -W -Wall +TARGET_CFLAGS += -D_FILE_OFFSET_BITS=64 +TARGET_CFLAGS += -fcommon + +MAKE_VARS += LFLAGS="$(TARGET_LDFLAGS) $(if $(ICONV_FULL),-liconv)" + +define Package/smstools3-fix/configure +endef + +define Package/smstools3-fix/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) \ + $(PKG_BUILD_DIR)/src/smsd \ + $(PKG_BUILD_DIR)/scripts/sendsms \ + $(1)/usr/bin/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/smstools3.init $(1)/etc/init.d/smstools3 + $(INSTALL_DIR) $(1)/etc + $(INSTALL_CONF) ./files/smstools3.conf $(1)/etc/smsd.conf +endef + +$(eval $(call BuildPackage,smstools3-fix)) diff --git a/smstools3-fix/files/smstools3.conf b/smstools3-fix/files/smstools3.conf new file mode 100644 index 00000000..da5a36a3 --- /dev/null +++ b/smstools3-fix/files/smstools3.conf @@ -0,0 +1,24 @@ +# +# Description: Main configuration file for the smsd +# + +devices = GSM1 +incoming = /var/spool/sms/incoming +outgoing = /var/spool/sms/outgoing +checked = /var/spool/sms/checked +failed = /var/spool/sms/failed +sent = /var/spool/sms/sent +receive_before_send = no +autosplit = 3 +logfile = 1 +loglevel = 5 + +# Uncomment (and edit) this section to allow smsd to start: +# +#[GSM1] +#init = AT+CPMS="ME","ME","ME" +#device = /dev/ttyUSB0 +#incoming = yes +#pin = 0000 +#baudrate = 115200 + diff --git a/smstools3-fix/files/smstools3.init b/smstools3-fix/files/smstools3.init new file mode 100644 index 00000000..c036b8aa --- /dev/null +++ b/smstools3-fix/files/smstools3.init @@ -0,0 +1,37 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2014-2018 OpenWrt.org + +START=94 + +USE_PROCD=1 + +# If an unpriviledged user is selected, make sure that next two +# files are writable by that user: +PIDFILE="/var/run/smsd.pid" +INFOFILE="/var/run/smsd.working" + +DAEMON=/usr/bin/smsd + +# Set/edit this before starting service !!!!! +WRT_SPOOL=/var/spool + +start_service() { + echo "Creating minimum spool directories" + mkdir -p $WRT_SPOOL + mkdir -p $WRT_SPOOL/sms + mkdir -p $WRT_SPOOL/sms/incoming + mkdir -p $WRT_SPOOL/sms/outgoing + mkdir -p $WRT_SPOOL/sms/checked + mkdir -p $WRT_SPOOL/sms/failed + mkdir -p $WRT_SPOOL/sms/sent + + procd_open_instance + + procd_set_param command $DAEMON -t -n MAINPROCESS -p$PIDFILE -i$INFOFILE + procd_set_param respawn + procd_set_param stdout 1 + + procd_close_instance +} + + diff --git a/smstools3-fix/patches/002-Makefile.patch b/smstools3-fix/patches/002-Makefile.patch new file mode 100644 index 00000000..a52aee4f --- /dev/null +++ b/smstools3-fix/patches/002-Makefile.patch @@ -0,0 +1,11 @@ +--- a/src/Makefile ++++ b/src/Makefile +@@ -1,7 +1,7 @@ + # In case of windows, use os_cygwin=yes setting in the configuration file (smsd.conf). + + # Select your setup size: +-CFLAGS = -D NUMBER_OF_MODEMS=64 ++CFLAGS ?= -D NUMBER_OF_MODEMS=64 + + # Uncomment for Solaris + # CFLAGS += -D SOLARIS diff --git a/smstools3-fix/patches/003-bash-ash.patch b/smstools3-fix/patches/003-bash-ash.patch new file mode 100644 index 00000000..4ad16636 --- /dev/null +++ b/smstools3-fix/patches/003-bash-ash.patch @@ -0,0 +1,8 @@ +--- a/scripts/sendsms ++++ b/scripts/sendsms +@@ -1,4 +1,4 @@ +-#!/bin/bash ++#!/bin/ash + # This script send a text sms at the command line by creating + # a sms file in the outgoing queue. + diff --git a/smstools3-fix/patches/004-modem-processes.patch b/smstools3-fix/patches/004-modem-processes.patch new file mode 100644 index 00000000..8f0f4464 --- /dev/null +++ b/smstools3-fix/patches/004-modem-processes.patch @@ -0,0 +1,24 @@ +commit 3790bd05ed86b1692719df22857ef76c1293b01c +Author: Harald Geyer +Date: Sun Feb 18 19:24:48 2018 +0100 + + Make modem processes terminate when main process dies + +--- a/src/smsd.c ++++ b/src/smsd.c +@@ -34,6 +34,7 @@ Either version 2 of the License, or (at + #ifndef DISABLE_INOTIFY + #include + #endif ++#include + + #include "extras.h" + #include "locking.h" +@@ -8100,6 +8101,7 @@ int main(int argc,char** argv) + + if (pid == 0) + { ++ prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); + process_id = i; + strcpy(process_title, DEVICE.name); + apply_process_name(argc, argv, process_title); diff --git a/smstools3-fix/patches/005-smsd-to-uppercase.patch b/smstools3-fix/patches/005-smsd-to-uppercase.patch new file mode 100644 index 00000000..1b553185 --- /dev/null +++ b/smstools3-fix/patches/005-smsd-to-uppercase.patch @@ -0,0 +1,15 @@ +diff --git a/src/smsd.c b/src/smsd.c +index fdfa193..c9c8471 100755 +--- a/src/smsd.c ++++ b/src/smsd.c +@@ -3959,6 +3959,10 @@ int receivesms(int* quick, int only1st) + foundsomething=1; + *quick=1; + ++ // 10/2023: allow lowcase letters from modem: ++ for (i = 0; line2[i]; i++) ++ line2[i] = toupper((int)line2[i]); ++ + //Create a temp file for received message + //3.1beta3: Moved to the received2file function, filename is now a return value: + //sprintf(filename,"%s/%s.XXXXXX",d_incoming,DEVICE.name); diff --git a/stm32flash-gd/Makefile b/stm32flash-gd/Makefile new file mode 100644 index 00000000..fbf7a6a5 --- /dev/null +++ b/stm32flash-gd/Makefile @@ -0,0 +1,45 @@ +# +# Copyright (C) 2012-2014 OpenWrt.org +# +# This is free software, licensed under the GNU General Public License v2. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=stm32flash +PKG_VERSION:=0.7 +PKG_RELEASE:=1 + +PKG_SOURCE:=stm32flash-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=@SF/$(PKG_NAME) +PKG_HASH:=skip + +PKG_MAINTAINER:=Christian Pointner +PKG_LICENSE:=GPL-2.0-or-later +PKG_LICENSE_FILES:=gpl-2.0.txt + +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/stm32flash-gd + SECTION:=utils + CATEGORY:=Utilities + SUBMENU:=Microcontroller programming + URL:=https://sourceforge.net/projects/stm32flash + TITLE:=Firmware flash tool for STM32's serial bootloader +endef + +define Package/stm32flash-gd/description + This tool can be used to burn firmware images to STM32 ARM processors + using the built-in serial bootloader. +endef + +define Package/stm32flash-gd/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/stm32flash $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,stm32flash-gd)) diff --git a/stm32flash-gd/patches/001-add_support_for_custom_gd32.patch b/stm32flash-gd/patches/001-add_support_for_custom_gd32.patch new file mode 100644 index 00000000..0745d352 --- /dev/null +++ b/stm32flash-gd/patches/001-add_support_for_custom_gd32.patch @@ -0,0 +1,10 @@ +--- a/dev_table.c ++++ b/dev_table.c +@@ -143,5 +143,7 @@ const stm32_dev_t devices[] = { + {0x641, "Medium_Density PL" , 0x20000200, 0x20005000, 0x08000000, 0x08020000, 4, p_1k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, + {0x9a8, "STM32W-128K" , 0x20000200, 0x20002000, 0x08000000, 0x08020000, 4, p_1k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800, 0}, + {0x9b0, "STM32W-256K" , 0x20000200, 0x20004000, 0x08000000, 0x08040000, 4, p_2k , 0x08040800, 0x0804080F, 0x08040000, 0x08040800, 0}, ++ /* GD32 */ ++ {0x482, "GD32F10xxx High-density" , 0x20000200, 0x20010000, 0x08000000, 0x08080000, 2, p_2k , 0x1FFFF800, 0x1FFFF80F, 0x1FFFF000, 0x1FFFF800, 0}, + { /* sentinel */ } + }; diff --git a/svcontrol/Makefile b/svcontrol/Makefile new file mode 100755 index 00000000..8d2991d5 --- /dev/null +++ b/svcontrol/Makefile @@ -0,0 +1,38 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=svcontrol +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/svcontrol + +include $(INCLUDE_DIR)/package.mk + +define Package/svcontrol + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Supervisor control + PKGARCH:=all +endef + +define Package/svcontrol/description + This package contains a utility +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/svcontrol/install + $(INSTALL_DIR) $(1)/bin + $(INSTALL_BIN) ./files/svcontrol $(1)/bin/ + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/svcontrol.init $(1)/etc/init.d/svcontrol +endef + +$(eval $(call BuildPackage,svcontrol)) diff --git a/svcontrol/files/svcontrol b/svcontrol/files/svcontrol new file mode 100755 index 00000000..d2c50317 --- /dev/null +++ b/svcontrol/files/svcontrol @@ -0,0 +1,19 @@ +#!/bin/sh + +echo 506 > /sys/class/gpio/export + +while sleep 5; do + temp=$(cat /sys/bus/i2c/devices/0-0011/temp) + if [[ "$?" -ne "0" ]]; then + sleep 5 + temp=$(cat /sys/bus/i2c/devices/0-0011/temp) + if [[ "$?" -ne "0" ]]; then + echo "gd3x: svcontrol: i2c communication lost, sv will reboot" > /dev/kmsg + echo high > /sys/class/gpio/gpio506/direction + sleep 1 + echo low > /sys/class/gpio/gpio506/direction + fi + fi +done + +exit 0 diff --git a/svcontrol/files/svcontrol.init b/svcontrol/files/svcontrol.init new file mode 100755 index 00000000..7fc3ed68 --- /dev/null +++ b/svcontrol/files/svcontrol.init @@ -0,0 +1,15 @@ +#!/bin/sh /etc/rc.common + +START=20 +USE_PROCD=1 +PROG=/bin/svcontrol + +start_service() { + procd_open_instance + procd_set_param command "$PROG" "$1" + + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_set_param respawn + procd_close_instance +} diff --git a/svupgrade/Makefile b/svupgrade/Makefile new file mode 100755 index 00000000..7231c2c3 --- /dev/null +++ b/svupgrade/Makefile @@ -0,0 +1,39 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=svupgrade +PKG_VERSION:=48.7.1.2.1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/svupgrade + +include $(INCLUDE_DIR)/package.mk + +define Package/svupgrade + SECTION:=utils + CATEGORY:=Utilities + TITLE:=Supervisor FW upgrade for LT70 + PKGARCH:=all +endef + +define Package/svupgrade/description + This package contains a script and fw for supervisor update +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/svupgrade/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/svupgrade.init $(1)/etc/init.d/svupgrade + $(INSTALL_DIR) $(1)/lib/firmware/gd3x + $(INSTALL_BIN) ./files/gd3x.bin $(1)/lib/firmware/gd3x/gd3x.bin.backup + #$(INSTALL_BIN) ./files/gd3x.bin $(1)/lib/firmware/gd3x/gd3x.bin +endef + +$(eval $(call BuildPackage,svupgrade)) diff --git a/svupgrade/files/gd3x.bin b/svupgrade/files/gd3x.bin new file mode 100644 index 0000000000000000000000000000000000000000..26ca83ec44b057387ecfcb7a71fa08ae77387a4c GIT binary patch literal 62960 zcmd3rGq5NMuw{>}du-dbZQHhO+qP}nwr$%s=EpCYnwsQ?yH*Fgy0g_IdV2u~vtkEH zCKigA1LD*CSS_!po{B*ENd?c$y1>_ z?d1?1>#zEX2u$gE+jUW(VVT(ZO!jgHZng4NvLMd3#v;-F%cm8GlPA0PTmc^jK?^$4 z-i;ackF+$T>t*BH8s27ec>g=EGg{m%OT<&}g$ISV>reIiUye(l4U`oIiVlqWsB^A{ zTJT@)4}+*SR+)$uNE9^n9l;`MW zqp~|58Q}O?5V}+shjl-aHkWDBZ)lnS?fw6M`+;+kzJ}dTQrn1t;u%uK`XS<>o?B%PT);L8gaxfVOPhe1Gsaai zr{2eW76`e9vFV|`Ni#vnY3P}Gay=wMaW_r^a|L=HinTYbN=jJno@z=NeKvPxYW=g^ z^sl@q1yQw`kmd#Wx>a0YNKS%d;|GcraFUF;825Sq)O;>McsM>BMJF*^pd3lDH#tUbDzTx91P12EnRz+^Gc^OIa_G_tQAi5!Q~|82_iAft z0Yp3yn7WzPFa@)O#om7z;pOTn`oW2YgCjZfLK%n(0UQ@ip8-DsJy>Pad`&bsrIQ!# zdH~9#@DInsEsxeuTOJYJsvkw{c%GCH4LKJ>!&wN+SV7G^< zO2U$C#Ak?P4m>`95UYaK7=q-Q&!2yZV*6MGFd#W^1@>kUGptce$NO;qW9?n1jNYvU zkd{b}Zf4tD=@eXrYR#H6Ri#?Ytk-;h-|no$C5Bj6S$6TWX!$5~H-m{S5|)+E16@f8 z7@H|pL9rG?WX$OkjhFGgDxi1axl$>uT2*|RTJcB_=8dBYZU1g#O9VWv>7p{QZ4JHu zqxP~_9$t*m^Do#12EWdkoK>r`XQj{pPhNlV(Hi&G1Dp%aMS@Gt$fwc7&*5ucbR2a% zvO{PI@xL7khXZM?R=)pIF^(dhHZRX`ya8Y(gMjibV3`gwHr})h_jqR+mu3ugH3LOL zG%d^ocQob2J`ppsI-eLU>sg3LY_62Ko_D>;_a zCdVD4XEHx0N+InU4?I!dK3T;k+y(qJ%v@o=@2D){Bd_5SvhT=QO=DjP(n|UM$`X7j z47z^DpfVg=WM4V8tmlrQOr_8J+H6WPzJ*Ix8E1Z&5U`K~C3$cx|dSnG+WkJ zCUBJ%`BId#S%ciI=_1TR8k4R}HLeUq7Ip&A`c(kIF~UB#o4_vx$EcL({w)Mw#Uz;Y zn71ZaJ^hN2{Or17=pZf(S&4F$ZGl-L;m8>*H>BLfOdc6cENh2BMX;E$ZuU$9IR_G< z_)I&NeaLVyQxcNaYw$J`HItC)0J%B#h4a{*@CqI28U>6Kxi6JjkwJd}t1cJCfKX%2 z+M0myW$wDupL-k7gsy7y^qu95WHV``Jwv<=w6Z7V%|YShkeIJ3%%q!p{l{sTU*hxR zaQJ!C6Elh|K*+PCP(*~x8(UcMaP|;kQvb^&0?kVppPZ&;rSR#eiC1D>8(Bj2GX$ysA zq232hZAGO-JQ)C20XgUrZ#=;Mqd`Q|7Jy0btcV6mWt1>5npY2;W4$#-tQ z%!_y1aYoS{*)?uj0J5tfZ)$x&#vD|It^ati%Sa!)4qJR~jrn9{yf7yn&#q)(bl#(% z!bg?e-+-av&FI40K=SQquU^dR51=OfTz1b)>64o#KZ%pQVPAT&+^zck2sT#7d}7hU^~S1!|+R zLDz^)bsiW9V5$)W9|ur;F_SOm1#AjjT6_Fm7A6K~jN|@U?AbHalfW<}3$|i9*cFoH z24wmafLzDP^QSR5IZY1ak`8C; zd8#x=TklR#IuNOwi^d0sg~}uk&N52>YcJk?cmu{V%nC#5r{;{8 z$Mi!gB>5qvr{aw79<%PE0$pU2p&QR|ATb0w9CNy43z8@b9Nj7xUprajNuD9qVjzF; z$Ku4={0}4;`ekf`M_uiu(t}ic7)gKXJxRR8*1~!`_BHgW(6yrkYy(;(!kr!C;Xi|t z!8Pw`OF!51yY-y5RYWB5k>hF`1h7ipD z@j}yW2GuRXn%(UB+X#38Ip`z!Slkoq9;ZozW{xHH2euN?!_oG+gnF;zS`F2}L-Uhv z+U`F$eO)cNUISe019ZtqsLim4rNb?kL#G?@$H)x0?jq4(ElZNTH?BTkjbVYxbXm8Vu zK%Q04{pGl3+fJ`B`~!*lsQqG@&2G;xaC$&IHsw3C-tf%qN0=oL3o-smls56a`mw+y z{&ir>G8OyI^K+-GH25SzP~%}p8Y~zt{sF0db1qJ;}4hrG-WI2zF? zttB*yc~FxED6mUd64t0qW>iv_=TP67U^KTisD=O!4vo4O8qzum&ke+2ef0z$WfszD z?3x|4SS~IBq2lbQLK(LL&k;{lfkx$Xe`P}mh33dgjk3(pH`=E5-2wW6IzQMn5zdSg zWV8jIPYA4ge8xn3p(5RIU#CHv!~1;=ci3hG)9$(_KB1VDBSdmJ7*8+PJ;ulDfB;SodnE^V8#$ms83}w3Y?Ov1|_tTq6X~IjlilY^Y`Z} z^YP|Lh=aX?A7neiWJScJ&Dti0_kKK*?y2}~l455dH*1roqtrXHcuLbjWI{3sd&|4~ zDz#*85I!i&5UfFR6+Z6xrvY}mu*}F!XklF=O5=b5)yZ`+x$6&4i6rfYv!J z^P9V_${Ue8$b54c2@?FvUSkdru@kplKGoxQ_kCeO`CK*hv)_=|PXtkE?*ZbM$h6VS z<$y<&(^Nidm1cwY*uBhp|FDchZSBo$S2W|BX%bT9@k+)vtPQdh(n+`H1p4Rsva|!w zVO!Q&!GAE!0P;z&EBiS`(7%!e^rkftf>RnuigGI6~nR-eGv@V}xHfe;8S-xr>vjt5r`6>3k6Eifj-9np_ z@YNNnjPjf~SJ2D~J zRqG6sdA(w+^0{Sjn=e2o%>%PuH?XE387;&_TID8i$$j7=CZHilDG(RKz)+~}Y>SDr zz%<-LzyQ^g3|MB*)}Pdcz0+Mm*l&GKG04?Fc_3jxe!qK15mch^2y-q_ML? zQxL%C2h`4d{+BE>)7_xm>42FDwi~i*!(`02x3F^=*{C@S`7l$lS8LND_sOX#_Sh zID&(OBGDafdv(qr@csXsZk&Cu(bnw^Mu$$iaOWAAJ}b?S@5j--4YY-gg^@Gy2zN{E z9NP(?afIwQquuf>8JN~Cx%BN+Rdn%=Jv{jPV^ATw%wQvn3{gM}^S_op%&6Z)kHNH@ zo=~Ee&wNaIRfh|T2TYHR2lvmw-*ye44V6Lef=s#WBn(Be=nTPxNP3vuxo}5&-K_`I z$#dN_++uwGt(Z3bUim-@x>AtNoJE!b`;zpYzFWjY%Sx{HgbW7`p*Q*uA)7Fo(gFQ-%2#_{s7uZghTP?!ft zmgvKwWo2q#!NrkanWIWMC`TzT*IrJ(I9xdKh#s1I!I7)awIZA(xg-@ZUtZjImhtYC zfHi}4k)>{>+|fbK7@itBnA6xSqx9QTsoRt5MrhnoWatAo$Qn2gaw|s-pZ8wg(yAby zE*x1~>@`OQYei_fOIFy=x~P(hz8RA*NQORB>KpME5U?7*{Pda1`4@<)v&Cabfy6;O z;yF>}(o4FRVJ4(gAR0tgcprVVnO>f=IsJUx*VRMmQb(|&1egRf=}}QP;bQ35wkr`o ze;vc3!CLG5RyrbazaB3;K~<|C35LJ5D+gWjcfx=@hmM_@lut9`J5XXdbfA0sbXxX$ zJY7<1O_*XYU@DFWyhLK1c%fa7K;Ci8+gkxST2H%>Lf)md@6==eIpl-|$A-ygp1PP| zbPlUOS|u!lLhCja+n1dQV`6A)eHqtej%Qnz2S;!DKetS;$`@C!KkcD6Q62TNpc=08 zONcq6V2*#?)tUgw{;GvLd-%S8;R;|xBaf)L}k_K zwR9rWB8<5cPEB8;1Cq$*OF>_+_n)v6c_W1zyif{LHxZ0=W1sktj;KkV^A$X1!1tuB zwJ_2o4RD-_VYV3=^_&5-NAZE1F#p)Q*_SmP7COj$Q*BSdtxw|C2$k;roAOHb zwYqt0=DAgCIQP2q)X^UsSqXRnfU||k{OXTSlNr?g{4{U@*zo|(hh{dp`2E3{Ygt{tik2J5j+ z6y}VMK@eETgLx9;cf+@@a6E+k{tPFsJ@Cz;dU81v7NP(W?SfDH7@YKYA>5n|i6EqB za*iqw)kaInK*uhy`gYA*QRk-F(88Z47M4!Fe{pQ&vNE-0XT74d7V~DtD)qhN){eNE z{_s;n-s)ckyxugprc**6a!NA)aviU-8^0OC>I1M)T0N5tt+8!_Wv9rWf#MKb!8v1d zZ=XnZaSr^@Kx6)QJ7d9|yPV!_v(A-37$a{RIXzWqQ+cXKfA*?BsA7L&*CBmFe3)r7 zQSFWK!H@7tAe-)Ggnun6%`_ly4S*bggJYmpk2ef5NEmZt%zR~CVhrU6lTchKCn%G8 z{wpVMj4z8m7o%lzz#Y#}-=$jwBLWV8djvx(h2(>|o$~KZCcqI+?|cRbD3<_0OFD~h zs;`k6Fcer!XM;a>trF`ca!nz=E3fdOaxhdH?7dNz?F(!|ZI*G&?PfK^vnnau&PxfC zY>$3EeK)`|lTl%#cK_6Fb8uuFBC2Wu506)G#V@@LL?o|p+*6!!b^-;ZS=kdH?Yr_A z%$uO$R1HrRhgIY~xZ*Dl1bPoG6348ta}I>TM&m(D>7M#Q^G50e+8oaYls#=Fg0#P5&3LGCoSqa29dC9yR9h+D6(Oc2cjZ(i$Rg+pZG( z#pW5k4oV7wue}4>XfW>3|Jbmqf9S%|Cwoal=12Z%a(AByaSqOdh~TOuR7Nzhkbicq zQr6Zz5ZqX?yT^N`S`32rjtcPv;9O}4bPMer{#BQL6j52zYf2!TRaQ?uw9LVgnK(NU zO`qg^0Im2d-lDEqhhWQE0M@Fvy1_iGHMr?lmbU_jNyb-?$s?u5dr(UQn%*{R>VdQ3xs%Bgy@{ofsRw04!HmN5zSPCifGwqcC z15R;gkpuKv1K=XUCy7?=D_wZCa}kI-6&qpCxFsXtGB*&(dfUP05{ZlR;yunG(!UWY zz~B;OFu@APeJ<#~*pIUtz1L>8CgIJ^+!eF0!g4Zos|$J1ZLe#8p(DEgP8h1`V8c3O z6b{EVks$==?#V@Y1@e_=Srki;R2>QSvrM5s5Y3v-8u!KeGwW0>iHhS*T05x*i3qvw z=!fgQg_}Ry@s{Rkhl+^l8`?5^NJn+FV}IbG)>TCW(t@rqlAg@!hIR;rgKdt50~xjy zcB2y25kHMinvMaWV>UD|dTv!$%p%S;xe)#FCyXY?o?S8 zy%p)D+%|%16MqaAA{%QeK*v+F&cEWt?KGkdCd8^mNg>>AnOC8#HWBoT@PfsNVCTa_ zM8k}9+8dh+YB_*5{%mOxwbFa$(+SvL>>abUeD&6he8F(2Q{L(;6dKaM_Lwk{ z7ZcaqC4=Umnh@ZmMnUoHqt&hkg|w0z&q=QT3F2z4hlEALWg#B>PUmpG+fqw?kMFo7 zSqy+oxzDj)B=m?_KzQn*WQ=vZ;C97uG@!VA2_mE9M6=}NQN2|GyG+{2!ifjbfr&j= z-P#KFXbkreV?4h?6hH_OqOfEyhm@>L+@(B41E(FM&xA*OfJwwC6T?qIhA*Q8Zy&pK zk-k}&e=p9ZhrECB9=BcUVTv zxV6s{^o7h(I4f;4_qIzhAqVRL#XPpA#mL#Forb&?2AulfBXL75iSDs@Lh$oghJU|4 zMTy#Z71`@uO&W55o+MQD56!!b$4ttVCp=R4g6^l2dkdGDuvq{t^@%M2ZhbN3 zQX(-R2@nELBHhrD$I{2l`>M7o$%x-lB_?}&E!Au^vTZBi;g+4xIS{*wSj>bWWKJMW^MUJq^M0v;3X zrxUxA0Q!Mm;w;4FZm?5B@j|F!EbkZ&A+P0#2|Ii-zAF}_jv2}2LGU4 zTa~MMkYa-yPt%N9ls=XvyVB@L#R*J0F-^=oEYte2<_Vu%yrRpud58NSAI0bm2G{oe z!LI^V)?$lYZ9^_I4i(+61y$gD5#7roSKBKjmV#y>t8 z=S$}@$qos^{ez;-br@#2x-!sTPIIp-@YalPm>#~yt?9^`Yb@yMwT1sf)RE6oL^Pnf zd+Y(PC`Cp|k!6IgfT5|4j(GV+FmgjllnLqfWfWq;1o72P^PsZDLzEmbkRmscX8_+9 zTuNZApNglB4;#-LbNxN1iq*?A)sQ#~csK}eIP-VJ0}K+OA&2)RV3Ii^!T(e}PTzP% zGxj>6PK2yNSD!Xz-M*Ninn!gQ@5}aYT9@^anzNQc*L#^Y{`0DvO({&q$#Y+rLuuHI zj!2|xD@wnCh5kcO+!7g@ghS~!@oa}>d-S9Wk~T>zA-LS;vQCo$2nka~`7fcZr|CH_ zB$FZ%z^m21c)_%ynd&w*>}0j0mbZK|u=dWM4aJ7|-E5~20N)nD-um|7qGbe1*DF%q z&kTozte9$Qv-AZw1cb)Yo~HAzK%^Eoa4FiYh?J5(O4OFY6>**grCR5D{58vqrgPXz zf0Nq5LG6uy4FO?o20DPR((v@YNKeAT2u`uHXZENvR-{#qNg+gAH0J<>rp>&m4?FN- zx&+n_g%D^Yqy%*q5=_q3=L%qp&SU6BL4(J9dw?5U4LOvX<+hSVP z1%Aec;EAAAkGV^BBf4}!#vj})O63~v#nH+zqZ+z6x*a0AFj!;O8Gx>p`qjQ@IO5)y zd8sOD$&i-8VsYqwma+>U?84A^<>kMAA;9&S98rC}Hzn%(H#XsrvrfLYoSZm9n;<=D zk>El>>$L|Iz>7YyC%CcZlYc|gIs~eICGps7p13OLIYJ9nMvu@+NTo0XL11SniGpy0 z7@lYxY%sB6d7JDZe2T1wm6hV#sHPfv_1?XA^9B*p+FGHEjwV_>M0lkI^}xN6?C|Aq zR>?wdUO!6^Iw3e2$KZgKKIphgsqUzf9r#{A@VFvgE`DP&)ci*6m+_2X3;Z^ZA#SHv2aT8gMi?OozvXjd=U0w`Sgej`1XV>~5Vpwfo6h?x*A zA873*4?Ra7tlSNM<_3DMcPnPZ_s1V${H^g@JHseP)4@_tTtR*%UY$E4|p+Q+`AyCrt-?Y)~B9&ijLr;zbjn-Et;%HEi* zgmAdD;8X|-w$zP+%4uz|pGt;oW}hwEdx0xWhkp3?<^FBPWootI#eK77(;-vhJwkW= zj@It>WkPyqwCviaPoV}i`B<>%FSvqFTEkV~4<<=#U(qT-q#AK9*%eJ64W9f^NB_2M zXH#>Jdv1-vY05eB5)qrC-=c&VZs#Oj%s5nW0P+akP|fXOd3|O#4j{j+?fL^98=^a4 zrDYMkz-g71byvO$3nQ<8GEklv+V~K!L@>(vDO@OX0}znS&^KT~(-a~2!3oHu-r=eM z(AKP>L?tYMSzDU$r$>DJ2I zet<#eIrPHb> zcULp9E*&(x8_p711FnkN9;R-8AN_t0AQsd&#VZeId%X;kuwGdRvfNB1ZhA?bkJ^isbp6a{ax@n-lcU$P*MT?dN|1N zRbA(m6?y>RgJ@5W|8a<`z$qudbqDj(MZh_K8gD^r@Nm#&*X1a(?GW{xM_PfngKlDP zWPexjqb4@sa-%T@R8hQer&!)?D#KuczCtI^ZR?Z^i|edQ<=*W4``y#ZXQk9=Y)$fG zsK0vnXLHs&z%Ylv?_|cE2wTw?q?QQdD={bEb@YA=>XJkq;d*9FS#pI*UKB6^oJMj8 zxT7nz6AYD73D7XYd z{d;dG`zxc1A%3~sRD@<`M=pN9dn5JCo4%(j`YAhHSE_8?H5VZRr+rFaBh7%spu&mH zKoszyC@9vg&&DuxUedzfGZhbQVarK7~!D-rjpor?6^y7Aj?C2YL6n; zZ(R!@;w->z?K){a`|cx1K;^pIJ0cTGiJx)jT8o>rn2>zWcOke=Y2G%)$%|Eul(HJ^ zN(KqBUU(nCI`Z^XOx@>U%r&g#a7LbnH4*sh=LwJ!u9>-ETxuZdU~3O0ILmxPO?qgo zUQ0!qD(bIP%*e|k;ziv|>ur=BSSkE?g>%u8W%I{^PO$k00Xqlvp=FE z@p#7F>?t#rHhG+FWbVqXaX1`x#asByhNJ}#ON(0gI*C~mRQfM}CRWJ`zf9|B2|K4J zJYCP;v5-mA3?l?jVA8O);z=o8PUpQCjmCoV*!98+2R#L2l(~_1S3<@_q`X z<&2Dx_II;*La#LYfzd^@+;2bv0_#}~=tz9^o$+0{r+RV5JO_7WIyZ8hNqIrM(h~0N zAIqYwLB%QsEz?bWP>Gy2%zgw}GKP$4OhJ4S{5{rHO7;XuLo`8IJ~Sx08@&crwHEe` z*i8Rbq(2e$$^f8vIJxYlvxF?hk*{_ONJ@gplJ{HofSaJBf6qcQZ!6utFJkRQrYG?o z8-5B^{Z>IGDHq5U*B*U1?)?=W;{b6>ON)%jsH%B`3hkYQ_iF+J1&K>z8MzP{aGn&M z!jDV*N?;fX>oS&?4}zQlHMFF3x)~Z>PdW$kqDM7|ZRqk>%WFcCL7=Bp(Dm?Sg2^0f zfab2L5-J)w7JJ=r%f#*zA|8?eMyLJ0e5zzuRkvLEEp>lQ;AlLI)CErM;2x*4$a`HaIDVFDmqCavH^FEQ6jK z#Y3`x;}jI$%aC`;BQ#scbYj19GHNOgPT9yZcRz2F3d#593QPGl^7I(fLv67y+e^iz z7D_BAb<*7jWWHZ~=pc!;o~yJ04a4yv9mG&`^{er)+*=TSDFY2(HG?bYLc-esVnRQz z>GK9|ndV5i$~cs0kAE~fl~qccaUnnfJ@+QDjuYXkNgoJhB)A1nyoo=J z+*gD#aVy1YOH-8vbAM8I&zYe&7n#gZleLiFEW*~Kaxf$NNd6&HcIqxdld?9NQfgfI zXfFx^OFr`Q(_l0v4ps^-+?Z5H=$L;V-`}`p%xl0RL;++;*m{OFV(EOQ7@}6_W!5y3 zmYuhVijK)kM9mF0bU~@)aI?P;B_M@wny%b0)R0+PsSL~AcvC`@8^(Q^ET5!`uH|>m zuPt+^E!uKlfi*wEibo+MhdGYV)NGBLo{n`&>(K6>;SdmDF2yQ!t+_Ovv(M4Y8f@U2 zLcB1#tPJ!Q5tosE6`kbTjxW6SJ&@fSdk&XtVW?d` zCTxDU92J*hk%K`Z{oGDlxDRe6EUr06!Qb|+4`1L6h8L2mbnCm(rx{3$(en#&*7Lg5 zTeMp{T|^5W9o~UhU&CJY=>fVMfI;(X8A2L<8HIgefu?{%#j2;~XR6lRyKLg>eug0q zPeOmvbO%BVtCs50a@wBFJZj8{XBv)Y~c)0X=M3JT^6-qp?3PHcQ<5$5pDh*G<5?x)giQ0THSM231PaF3!o^NnhW(`%5xO?zh+V1 z@0JWVU0G&MigGhje^qJ&>{shy(;$+63ZT=>8N26Zx=#Aq3TF)7$HD#IvQAr7ZJH+w z_=C&VNhxYbD6kXmUrWm)7Ji65(@EzkzfjX(dzYcyb)z}&IHf8NlugRZKOkwPJxsj{ z5lp>~O-AQO;)DrvL~Yxl+)*8AYnuazeG;tmK;BC{{d{>wB7~muK{aY64&I8ML(=_b zkBdIfCRvaBx@7-E|6H%U93$TXsM_A>@>DYQlr z)-MxZEa>9m1CBk8UMskywe#-Tod%$=;`3Pz`#BfxiE08%zt0eH?>b~r_tiUH)8{h8 z!4?!py8~B@H&wIa=9U9{ov6hMN%samj)CPQqtr~6!B{J`DPnZTh6}kQqy`yC-N1$6 zH-1@^KF|cqk|1p92RF(3b3#UDH;8?Igeglt@T3CPv&2K%`T6n?oB$%yI8!i@KGU72 z8y~se>~)o}KRG2fx;{ z=$_xnQwyGF(@bNs)?~^OnGBq4Ob;`s40_kbb;1NoF3h#Aw^J~M0v$(b6_*%93fKc& zNG%k7?#M?F2l9VTZ;|?~2UqFOFnWGm63+>f9EVkV?MZ83(;?{@fFP|eTs z062Kd8NvAndyc~Km~17_ao=siaJ9E;NEzFq$4Ec)IO6E$1J1AV zixOpGH7`UWkc4DaJmHjSXd9I67WJ$VKB?7B9`3;K&LO!7xfaC_1JOZY^@KONmX7ce zLddi z-%|!$<)C}^k79P6<4P2iL@&?U8B-)7eiZH)deEzk0rkp;UMTx(Iy*;6RSXg-lhM+X45GKRZ zxS2I+4=C#&SCwn-K$s(;O3ycPrr^e&V!tOu<*38$N^926z9PQrRdh`G>h}WPh;L; z4neDM0#cK`SrDLN#gFIb#+4Y6lS32#w9G9?Nte_+BxQe^Um4U!n-aDo#_0Sw>q~%A zj%1MCI(=*)Lr{WO2j+K;(F7wx!_97&QNJ@IEb64VkqRLM#XehqY?zq<@2>%jM7wp{ z;eJplM5q)$h%aSk_d3&7ZTim)muF-*5!^8~#>c{~-o6x6-vOjMA*nFsF8;fZ0ZSjR z>&=2SQXe5_-J#=4HuRk2CRxCWWdJULwqyX)osL)t*KiCYe{4y-jyPRy4qG2<2WGAcfS53+gr4gUBKpr4y`>VgB;+vm4gma{rp3Sc5ItV8BnbSG?%C*jS(vF7P5u%ojmT${4QG8 z@g_TF`oxE?j0?A8yd-7=>Ria~qU-KqZ>wh8UPhBWaKa zO^QffU=E##^ZismIOVWq&$+8ST@Oq^5HrIjxDg;28N6X^sL5RqYEy0#UXd;tfwu$( zW%5p3hvdly%rpXSLqw(>WKGR+u-=HPDis{50M`(7b4L^)Nt`{e-?oyY0_fJXJa!Xf zF_Jo(2~|@k^Ej!w#_MW2W}mJEd9!Aa4(Yue))%`U~__ho<|OG%okH@O8Hm-rCOu=jZ*2;A#@pLM70JHaDq9NFt;% z9H_^yr!$iDOX%66J_^T|?HZz39*JOlRk>)_xMdh&^?#GFXs{vQ)t7P-*6W%Zt+In= zSJ$Le$ah!MYD8ZZ@s9BJ6s< zy!R5(6a9Y{x=_*fBl@NuMsdD(TMz6W|N4x%3re^BE&Jo$yTv*bJ99-)%zlk&23M@EXwJQun+$U<+3{tb369+HaTG=dXI#YHgwfvw|OO2%iUA6dBmJ z0njawCCOS=#Qyp%>px^rg@8R+2;ncbaIUPP$tjt==>J-0>QiD?{p39L?5>}!4`1T0 zzf&|30Bdsc$srQ>Y9FKb^*Oo0T8j_<*t;6Ih;cciLU~eeU@3hyYER2IWZWFPGOm!9 zW*l9Hl#0|X^X?z!6RQx?mv0W2tpO`bDSq~Ki%(I2xUv!cT)AO$)EMsYHo~f*2e61ygh|6|D>Qg@l)+c~S?Qiwo*P&yR0CLd9Hm&^HZQ-KXJGcb3O z$)$VK<)_9FLYWZ#hx1SjHPG^_4!t5ggo>~WRa7?+UTvhU9{{If%mK_SU~J5}apjFJ zMCHBqLn_45DL99j&F0#!MzwrgIE2;hq!O#yuCKv)2eMGF8Fbuq>W@{LH*06;%+1WFoV(} z_Otrg(5wLishFw~WB&_)Kez!8+&l)~I5c8Lf6VV58W4T|l&>vJ`cdZgNMB?k z+gM|+QB&@Gyzzv%(G_SW`mvNrE~ZDUfX*{~+9|CY$(>#!hzD7_;!b`GIJ_nBF*gbO z6MZ{!rDOkoBu-bi9Bw(~kRpgL$fA$m0Pvw8b4>t9lCxi>etv@}tW8lt433eQIjE-_ zTO?s`j}e`RMY?)G@fYsY3uT`Jw?RsSy*wCW>Xgd(12d_I%4ZmmLW0_094z5WkzJh$hGu66Y~`sscofXK9lY>JQ?2% z-A7B`KHcS~cDAA}1+MPx@*i=&ytnz*+45F4XK|*Oz+Sh#fGwkFnfL9Jno)QkSG9NQ zhxsspM9X!hB!`?Sggt;rbTWdJJuk%dmg>MKeF4Zb*!sdNHc=M>UV!a~P}#lCnCwRbL!+5vdEG}WY zFq2`FjB+wh0}f|8)QdT|a5n?yD4AbhNZ3 z-+iT@@Q5stV+`~unM7cVbNe1+%~#5% ztG+-IS0(pyW*FKFqZ?FwlG?r1ZOu2$Ooh2RD_q!LSOTW!*QhL9^o08gHTG%$*4U=7 z7J6-!sH^(^=iNxh%nC8~k2#sfhsi2TEn{7l&BMJvM6#48{Dtizqs{dQc{FAFQW!?A*FfHF;ghzqU4d~AYYe!jJiA((}6@`w9>nuOPRPFVGY zJJ?B5qB_N-62A&K7oxP6&J_3Sc_yCEf>KN3uW(Npmjhz~$|+tObK-HXqTmRCgBgLO zEq6^iK8>g4EEDFg`|3r>JT=GjS(kGh9gWKCafGQHHUy~<1@YBas)~FeN31}gT$}vD zo)7#+{(yF+a2_Nrzv%^vi{oqni%v_$nfdPbv+4_GEA(}+NLX|H4Qr$_&_iiZJW*52 z%Vt|1SLdq*%u0O4xa<3x291fB;(<_kJ+y^_xMPYQ5altI*Gq$Mp`CPJM-nvzwQ%2OO;4J#KyS?p@yxaO-!M!V z%Tq65>X6@I4@W-49g}6x1=(x96>FYd-LEvxtesrw-~uNmLfuw&*nGE7o4 zP>Jrr8`U{S8S85{m$CMBgb(VouqPh)_xU@|CH~17QMflRuB?41fiMNb4CN4NCYj^NBt5AlbQ>tk<1TIK(#w{p$D75lQTWzri=vPFLjWtyLOO63qZXoGGV`|}jTkg-FYdk|3e zFjAHW<{j1V&eGPb*%%a(uIkGd9UFO$EHF{Ka(kOKnx+YC}GC+C^X^A2c zFsaz)_;GePW22%8WIR6qslWwghtU!{lU(ua%;Wkb~?9FRPmn z>e;R&`B3uUSX53KE%vB@y3AUb~aa;B0orSe)dxJmO6hQK3G9;j!#D+0&ANLrp!54yi zPT>#bcsV8Kvjfx5uzt|hEKiiMilo^*P!oX88Nd+cD`4-3KaP_9wGsVT`5F?bl5}Pz z*dS;usCMhH`-qi30YWaRD3=;@nQYjZ z3R$d4D1`2C1rr^xFUi<4UyO(v2c*1~aDhv6%aB_9b*|dz(PNzF0RwF$e_WaR9?}k_;Yx}H`V>#V{<2z>A>q_6p z7?s0ayr{N8_{%rx%$RtpKW)q`OFQDf)UL!=w{5N}`Mba%Nx0A@Yj}r@UXRkOFVSta zjDVtD;o|IW#oces3{8f+iye27?FoerD~OPDCo z_zoMgZnqZQ?FtDZaVHu4R>sg}WmDq)67Dt;e>d-o|8<*9KjxcxBM-UU2QMmWEhsH; z5SotN5`P@s5Lj6OBNqzzoAEww=;vTjBxN95=G{pRp+JqjQw4F_GR5%J`(S3P63}R0 zUEw*DS(!s!*5n+|CMt53=~ZxXHQqs+^MyoE$*&zq!k zr8bu4@Me5&f***37L*DA@NwJEX2@G z@RmKk!CME)oBZPGAm=A5YAA%EHgf>5R-2Z1v|#!N=rC~_~pY8Z- zn7BR>CF$9Np!%ewTa&WcddH)%R<<-8r0`?iexXxE!r~76Z3IBb(TGX}n|t^~bi;~h zPS-aLr*DjG8@L!fbOCg(`xF%G+ux&3j8GE8N&YSXbm!?QE7|a3h2vvuMDxk83TiFl zjuQ$aC}W}?+yy5Qaq~U-$h~^pH`Z02gB^%7_5;ZZ8B;m{?gaaQ ze@?_Ly3(E_W7?R$h(u3ob|({z;6N!r3oTWW)DL+vP7&;=mzYzEX@eEGzl8t+c{0LmIzP% z-`|-2ei-+-mHQOXdqpn_`JyS+QJUE_Z3|2Hm{`tPCi}aLz%*Ck1e-PzunT5eCnTCS>XM)KCa?lX4fi4w%R|XKVyzSZu6lsdC7t9)~ zM*ruMLd2(BAqW8lpM}-lkR>;nP_$Ub72Gv4J$%_kwEj?moU0om{ zWymG6>#BbGp$hat1;s!4fu=8Wpd$~&Oif%UPv;_ta(^dOhcUZMIA=R;v)Ukl&QNKV zhg%&r^hWgkJj9dbjC)Y&vODS9SG#ZG*dLX5ec!96nbTcI(%{j>I|01rAwnnL-pAiu z3+VgQ*u1{rhbQrW^?t3E{g!Lrhvu4MMKcpJkQUttrQdBa;PZnA&LmO!Y zqNIVfefV~F=P-T`w}MRPYDBeH`GttSum9{R*%1xQoUft*P2IVIFEv@JAm7mmQI&N! zRDB*qdpxo6l`c*d#$_G2we<5kkv456|4Eu`A^BSU>#Xhx{$%VX8_>Nf$8yx{^Q5Bw zT)^!BNMWeu6tAN-0Tt&IzCf)t=mnyF2ZC|&=2ey7I}AO+&#L)SCpXxIdm6j#iUj2yLxaQCDds1CP|Dt>9kGiD_qlDW6yB3+42 z+3Yc08?Lh!mIDm?k_)?@qixeK&h0coDOyjk@YhwF0&Zi8*^!&oZ!_BZ2pp9j$(Q)m zSZ=F?;6ZVe$Q|4|L)IE828cOmrIk_3uMAGc>6NMv;5f?GH3>?l>coa2@hznWTsoN1 z3fiyPZas!59@Hje$qUtQdJG}ZQb%y;h8-7-G7gFu(}slmaJmi?_)UVMU?`IQyI=Md zzgJ7`Y*2)_qmWRY&QJUio!Zs4(#%UmH*JrHLE8=%*bki_OS5{XkeT(s8*AA8n9ubebeKB)=GO#)H3 z#g^8%8u$cPnpo865}Mm&c&CMC-qPWmgrS@H;ix9V%jO1zhaut9%j4rSu3=Ngq4rKp zWb9r56FvF1zR2oZ-l#Gdu`XVEinVyOS(u{%3l%*^dnHv%^vk)2O;})PeWuT_w`d>> zzFkXPe#=^xN4VQ>Ss9j~$zjt){FR^AMt9ssMVa+okx3OllrI8vR^1EgiYZJln?iIc zBa2DO+|5MEn@eDdks^LHW}A~xk@71(G?SSC5P|&7LSMv-t}4iElX2LS906FxRPmY= zOhjl8h%?C5Bod%UAg>n@{k&}?Dba;BT#Ho?H<6NGUH%?LLjYP1#rn|Q_;~P3?8_6X zVs7(Ehq<;*Sg@nSn`{Z;pdLTx12#Kw2QL0o6B}67RuH|~UD{Kf(;-qo3m5t9@8MvrYPsP!tRNDn$S@HX%A*7x-?gGNcw z_w*1hM;gtO3k%P^GX!7Fzg7J5A>dE2HzlH$2tO)k_NddsSW{<&&o+Nxx(dk(xX226 zES|^&P%*2~xv-rt+0lZmHYF3~oVJfPKA@_)l?-mfu6kby8vPW!5&4dkYV(}N+aNdK zD#FAUP7D^r0+z|2VF1pgI_WJj8kto6Yi(X1O=$}&b*YZ))d&$Oal*`2*J)v@sJ^m+ zPZD*k#pgk;4Ecljp7t4zfY!8@i8cwWk%c%z{O}s>}A=h zh^rvUgO$bq#&zZP!n5O|ru znahnBlOXr|s?ozAk+Mhbx zpXDvPIjtF#EyqX?_^hWL!V9i?Mo_a1esX%8Aw)L#Q?rc>CQG{MudG{T#;3-Mg`sY6 z`m@?wWU{&He+g?WZ>VLLmV&D>h@bqZNa3iF#GQ9Ci5z^!JF-M=q?pF9h+V0oksWxBab*ni^H(ior?1ib$84V;siv z%-_YS*7EkpM3mgK_CM+v#EF%n=+dF z*ogcYuYfW4o&Q_7UbIe2-kh_pI?bjJn*bU98s3uL*j|N1kz`rYSX=HW30E{6Kaf}z z>Q!R=ZISP<_F#b=MzKd4^d)yp=@y!z4OCb1#Nvojl@@&JGKfcsq9#HcF;<{pX}qa^ zx&MwymEc@?r+hzmj2akc(x{CpE^LJ{bvmsAy818w;BOCuPCJ*KjOFy{9b!V~IIH&N zS)svM>WnXxR27*zlUzIbEy6FY%jO5g!I}qpM#m5bu)op-AGj@-yk;L2&x?IgqV4lL zxQBjGpZuPy()BNNH3pKO<|8~jBe~QXJk<`+x)@ub2s}&9|cw1;hiT? z-;*TUY>`76Pf!a~(>1S1;QEdQw*PS6WiMZ5(%Drog~f@}rRN-IZPHKPrC=o2lA&WQ zYwd^{XYg@|i46AfHcrIFrD$@1N*YRL zQPkPn4N$L0Z4fgpxTl7Tk4ZbPvh85auD?C`KAn;yHMu^TYBD2cr66wJgc@+sT?R8T z1CkfhB6c&`7Zsh3{%mnaB=){W$pqb9(>9tA;dWO5Cei_fN4%1sg|SxRw_10V)dRGR znBn3}bXw#EMF?-3q;ZSw4YoC5-Xu94C2Q|m&eQhGyfT4u38qQ!-7zmr zNAS_6Wh1XtEYaVTst%jWw3PP0z2c5K_Ve8^nDO699A)S>{Uey)pQrm`DawEB$a%|t znY!$l4!|T{7%4COrQZ8>F#cP6q=fQUg?-8Uw+DbZsoRmEI~|kbZCbGt!*!zlqPX&V zMeHxD_!JWjJ?FMs?KygAb8TUk`r;%@v}={qnFR%%(k$=$mrLkS4dEPS?vz`A+}8J{ zHyqn{hZmRePvL=D=!H{FQXtx+V>8pEMoaPa%WESEc9hUV1Uof zq|!^&Caf=f1B(iJyA_vAo*mdJpg>vv_#(?nG6qO>-@~OsoejcFQ4H7agOV5m6Zvh< z$R)$}bIe@U8&4PseWMnB zxv&#(DMiGpvy$GQgp{m?V&~q{c|AoivBT_MS^3V3hm6a!j@x)dU-Fysr)~3XfJs&7 zSNUk<(6H{@9QAZgUS#G@K1c5Qo2kcuT4-|fh4j~}0y|Sxb6bZZ zTp%Eg!a-?fdP^IN+A{u$M{j&^M7GO{so9YZ7_1pTs8O5dyq9=#zg3bH;5D^n)z3*b zQ#Bq5sd4Z&Q8c=+Z99g+XuLS!)dY~9s75;8vCQ533M|{J9D5L|i zKFZuLJ<193HB#c{$Uy&$_lcQC9`%BZ7KMmAy$$ksy`1;`PSW=`&s2$*)!HKLzFy9M zE3PsuZ8$r`{iGDP!ZPPRh*Hz`5)Gx)HN8{aS>f27TIuG&K=hfUu?k|pb$;3tqN$(@ zWR7vh#X=gO-{=P^2iHO1|$U;Hq{6}sf(t(n?>H$&Is!LDdU-l%E@pTsY zr#8#7S$=|SE9U)N514_8l;#f4I@&Yn6bw2Z!9gA3c zdJn-*fm6ivqt172ET&NWyHKZUwY=>7*^JPbu&p*(tk@+gBU#N~lmIZO+xhKz z7X|m10cPMAX0rTAa|u)^(;@1eepRX-cWo&K{2U)&az!x$!`5CH{Vwqy^^)ZAgOazb z48c#nm}AFzKo1j;B2$D#n0#{u@)i9_oygh_yaN>_2h0Wi{JEZlKo3LpXxdu%?vFn> zA~Xszy6?+N3cj_0guLh6xcQs#DcivyC5lbwqs9+~frZ5v^fgMJf}`0#cvC;xKoB=t z%Xq=5+FGI5g8j$nj}bH%FZ?wObmT3le+g!|YS28VkTGUDwuf`@ICVPaVkqZfVJL%w zaJ!fhY%fdO-mU%QW&Aw=tq&9qlbbp4V#e=`jzGM6CXFF|t^u6?QbX&8Zpv zV&fs`yl-oT$bs=2VxlZaq>y$irV`fvoo2hgAWx^vy=AK(%cV9jk10*A)yiW{{=~3 zX!qpkGr5(jx%R<~uELgr7K)L(qw-QzcRCY}%g*!sq2GmU>dFZD;RY{Ikjn_pN){b1+Qle+pRzmU!9=(gRsc8*)4 z-me{7OF<2hJj`~%TnUM0KJAZyZN`TXu_79NpDEpF^IU`}#n&_|xOQX$r;fUIs zfw^sS{T%O_Zn(R1Yje&3=1Ngr_PPi3q3tZn3qYgE>={caq`=OLh^HB@(&ChH?RkwN zJAGxVSS>8IMGD|AtA0D(Gi@eH1*pBL3+MThzs8QXOr4?5A<_{V(8@+E;-!uCHfV~( zJK4E9r-T=m(~U2rZqqbB?bBUE-7Wtu^mz}l`Rk2RvLVl!p=Mnz@_s3iYWR(a*Nrr% z92xWZwiK8kGU;rC;3-tJ=tJ9rdnc(IXk#OZc%ml{DTS%rk`GDnh zXW#-2GKAz1E47n5WB$*oc&4LsTs)Ui&&Yv;*)$n`5ybv!r^K04>qFCm zRDKF09uIMTM(#11dnEkXS%l?Z+Jm3-Diem@)ObWE`?PVbTDwvpu}gvOu+k@ z=k=sl@_7IO$}-121-q$Kq=v!l50aErECZWHz^7k-y#t~?!jsux>sF&~zIuYSKH|P4 z92rDICB0TIKyS&s-n&djf)iZG3sgE8Oki3mitv2=dj6sgu}6YPkV=bMQ=%9f2Z#q| zRew1ku_L>=8DQu7wiTy9NCFziV{zY$6iLJUu3^n`>+q#>JH*}Uib(cnE`BvXp?h}* zSxAoBS6)q8Q?~E@3v{`4Q*UwM6N9??^1hnO#ARhOT zJJ9b}QK*#-bvq6$mUKhf^CE>XLnk}pGIzYm!x^&&6t*zz}D8n6f17ri|#As8s_kFa1DskH8 zTlu-}Mz5rIxKP~@Ai>2`U!0{gGKwMF_Y{Os=p8+Py(c0~hvuW5ZM{LGvxrQ$Xwk}2 zU+{M6E!>SMRSUv<`DtuV)jSsX!CwS=!O#%3NZtL{F*N(|L<8KNwGiDRB6ltG`|DG? zM_(xIUK{P?oj|x21s!-m@hC>v>u*PAPaFHuaFVaAFYZiWI(~f-!X>yhXpd!3iF#fxzt=GVY(XKZux8!7 zl`VfapihXrHJRJ2z2hvrl(`t##43~H0MXvCl9oztQRy~RfNy{lUid@M{>|C@^DOv5 zP~s75-@(0h@l-%#P`8idRN-;Qx0@vwEiF70`I4FEcePtda za_PuJ53VgPw#1wK4*5WtzL+hslMzWSiH;O0drr=S6NpcSBG52|+BkH}z70b)SbdX~ zTt0QrT!d)A1sYI5dqJrsC}=l^ea#K~JDu*VUq&9ihW^)`b*H`yXnEpIE&V&7Se+($ zaB;3!NXn*={R)OKqH4b{pJOzjAG=JA4~0nC+BUiu5GAz2Xo5dn%d6_`+sw(cd~`i< zRKU;_+f?Ms{8YSn1^V_Z<^SvFLRnHcdM6!bxz-&6hI{9^n>>`<7JYDT4WI{_VY-Y(|aaG1M_h+?g}8j4G7 zMNysKhvdvSkm4-L7?`pJ!C53gsAJeWI>BI zhUiyP<<^R5B~9y`cyOt#y>hrUZ_x2I)5}n? zBZi#XfH-$c=CpOkkaNj%{)~gN=lo1Kq2bXC4S!^o;A%7wLSkgk0b;n_hPoLI@C2u1 zy!CXUQq#Dr7>~MvIFfLz(!d?l)Mm6QQfEV>E{S7=fbuweEp8?%8+8mbZCEzj&CYOo zeViHGe(_=oc%c@KJNJ zj~>jZ+k1B#(puTpEmx19B!U2r+$MSiH#!8l5kyIoM1t$$5i0z4*u~9d)B*K&efQ0- z3i4tB8}HOz?)B0mXSU3ojgGT@(%e)xm}5+({Y)qPo&S{**%wFH>^S_lEeWg+G>bpA zKd6=Q*H&t6*#d&!BL{30&(3?Srx|;ThJrxHk}oK=R3|OS(Jpi)>nAh##a;SvFLjI z;1TQa!clEg+&U0jejC-fZER*Zx=Hatr?r1|7&0wlg(i}z2facRsa%n(**A) zYe^ntqR7NdI zZ?n_hzn=@Sxx@9a9B^lIek9B*4)gAo^4AO=O%URju_V--OQ2z*2YJc5L^O8%a_^{9 zvj$9L7$LZoqvd|i`gt{HosPF!o%>dQw2uO4Zfdd?Use2neYk%-UwtZIaUo)J*@ayq z5j-bAdK#kinDw*ktxn8jj`G4a4!0Nd7}_+8h-#g-^ef;G$^r*&OG{-)s_^vPbz|0X zCgDh!#_>7Rz1Y}7f#+iNTPK}8cA{E_i^)(e7-EdyUs?->=eo~BZ^Nv%n>UW2=0VIL zCq$@r!AoQllPJ_!RLc=(?g&2Ls7a@Yncq}hsJ?ksFd%{jLW_cE>_WK6mG76hudRz8 z&yod*vP|QsWi%pMHeRay(-E>^tE>Xlk%gOS7UkeM}Wx`nG>ZTtV7?Lc2aalr=4aTM>` z??d6g=@iC@4CP-LFnIBazSB&M<@fCsXU9pc9Gk9=4@;rk*@o?c#;S`gd8Kw zgQ6zQc_ueEP*BU13vpHmQ#XO+w$8}&I+~!`MWk zdrGwofi88heDqEqNrdn$%;gQU)g?Jg*`L;pY@XQKo|?o%3J%MO#1q(_O1S3Mi=>d4 z&SpJ>21L8-RNZz)u$Kf@HTIX7bj{U+g=DE^kDCWx)RO|}uPO}~s!fkmR_Iru5f`Ko zhH)1NV%CA0C?eHT?Ix@Qm%bN6YqrfHHjnKxUyqk0P^#-ymSNNc1)2-(ZVpo@>I4Rw zkm-$Mken!IX}?4ZY08{h#wg0rNyP~l*puma_blN@zZdyD4XNGZ49>MD%RHrJ4BvRt zYW6YkR)>%DD;SNV5B=hnli%5R{Lu--;E%3d=)o^***W)yju=ShFio ztXh(kP=K7oC16c#>EN+fn0?-i2jz#`W)y3zK*Z6MRQlT&k=NHxbudHj`XC&<)gf(l zt(>n8+X!K{5x6BNHbnK6Y)*jQ;(+-S4a{h2y|tG}eO&L{<&w$FB<;qEUEc&FXGSvz zOOw2#&kk)bN-sC-G`*EEslk3mHL-j^`ZG;4bNNlaR=h!3F9eJY3FXBMbK^q{*M|Ih zf$=4=2OlGfvCd95Of{-sELnIzY>`AWo?(g7SIME6|lV7%LXnw92lBn#*Rgi z$wc3TE}T=U7T@ps4AB!xcpr7QNgQ`m231Y8rGDYOGT7!scWh3=t4+HiFx{RZ=EP85 zQa6lHy&A|49nazir{>6}Kan&vuut$S5?xYuKcjPaZ^$my>n*&N0~z4WFXIuu9gr5) z8SM*$^99BpvUn1U5>VKZ>bWHWPd@7y-hJ=GD5YZW_!X%FW|HAnEdhhRYEUWp-d3zP z&yWu9qCzLEORd1AFVoiu#r)%bhLtTqq{Y2wha zD~1!88t*yM&vY6&1P7=<1&aMqNmo`Is8#&kX64Q4tt2Tf9#d;_igj4_tdK&H^sr%0 zFoyDQ{$-xyQvXOslxs)>J5OuC7@G+=`4_3;@p-3@$aom3XJN{49+W+oKPwGTmOroV z`~Gpk6Yd>GLt_(2uh27!U4OT{B~Cb?A1F+M;L2Il55z7jkBqX)(EFV{y>0n>$#LBn z54*OY;1J@o`D^tUi-WoJcM_e`JAUdS1%b5$dNA%MAX523=;qd>v?ZR-UnE1N7^#O3bv zB&>u*?cqR+ik*V61Yz!OShSY_D2)*kZ(;vmyeLKn9xcCaJ2>&uYuT!bjlRJ_n2ZC` zqc#}||H_9ov0l2hi4rJtvF=dP<1K4c>2_yTMD;#mC&Udz8g-OBUO~*QZ_VZIoUE*AH zTNMVlC3-mN^JJHuM1BpD`x2Os?Fi>!XQKUCKSyt6ZEV7RlBwk%`q#v3gk|M3jg1>& z6w9rjPvKzs2GDkqBU8qvlKhYMd^zv{N^qVXxYURo{>Lw`j1`7-TJzsbC#e5r>B9AF znt)@2NDC*rn^wqOnDy&H>UY?)(%n`dF*93M96RQqV+ldzFQFX-CZA~~sf1ae)d?93 z+WNVj{d|SAs}}zzA~CkBrFi!029ncui)g@otA-ws+$zHnGb^SHoCrvGa55)64u@P8 zG@j<%Vx22-ZxzqLH+feapQgD7&K_&yz1yQlpx{yQ%I{&iP+{IW`C)E~$SF?;$G?II z)J7iNwknZA6WjcZe{+iU2X3FXfqjj7Ikcf+K#BL6mwkd+YJ|zBV~$MhHBaFTkmnKF zuilfRxxky0Sf~A9dj)#x>=Uq8($2bKejCG?XbE6_W38jR>N;pfsjj#~A3p47sRBe7B(DQf~g z+(&L*C}3<>SGw>i^|9E%BHS@t5YZ<5V*C1~7;%~%P#ZYu28SMfMFVOl=?k)`@8O9? zm_=+p43w?=#*?CP1fG}O(Npakc6OjkLy>}irBGjy+=?^k_#o0xox$WN{(Z%y2(jb% z=u?jxgx-4atGMP1A zKROYH#-wGk6C-gCLz_Em&xqU5hWoP~%GEMdh0E&E>$DCTMXMw56&U_KzZaAL%1+kb z;ry1l@ySv3oeICAJ{F&7FH=PNlo&6-5d`!*>u{}iFr|BIPTw0sbK69+-8j)DLj*;k zr2ADtdQ&-#ZQH;$8Tl9SqOh&V3YNW-GF2Q>>uwa68gv&*jC$4I?{#Yp=R&71spd;5 zzrSDh#H4EQMwAd?^Ci9yrP#OQDmx2F_up{s!H}8B2!b&~%$ki14=dynuCB%W?QMeKd+MO>o~J zS8q+HyD$LTK;teDtGtb&i;I8WQ8%O^+|)g(`jYzMJujv{^kG$4Hv799pBkU%M6;#I zGyL7TUmqq({V+sS2O5wtlKuuh!OTdZ(h_F>@{$-W{Y zY9eM5JMi5)Q0iNvb^n0-d;sXW)f)xuXtz_tiRNX#-9yF_&yHa)zj$sP=%lPTMVH-r zHd3OMa&QV(+6EO4OSy8{dYwKYuktXuup)XEl~tKc34X<96P;8H&DJfI=Ju;1Uu{th zEwb%Sj6etS@VYb+{(-TER307!_X6H>v#JYS@*_i~u{;MG7PS*gkKIp?RO%{v=m;RS zd?$Xt;|kHbBR`*1>a}Z8vt5U5nw2*3cIBQRq#_6$6;cgJkrRWk6!v4>u&6Ja-bVzO zMY?$I5j}F$$;0&UPiB9IW3ITNBV_|LWtkE%0vdg2&c~@d)fpNpnOw2R3>5GZm%+q| z36u1Yu*+U@oXnS|9=~}$lVzJl@vO?Z*oDWYj`2WLpYh0;8$PEXn|M2dJHyg?uuy^L zenP@4W=;~}C2WL^0+cEgFZ;vvS^(&U$TGgv_QWwS`fUR$hD|H7X^L_6_st5~I-b=2 zSjuv}+QxNK5@8c$kw_6!jDma_HOHj z3Dc-<+f&sV_^#=cboIqOC_?rW2{#&jtv|T-fm;F^BRMbwl^==}jH1Bn*?b5U5uebfepf#Bo9_y1`Je#zOH|MjIV?=|47Xz?uOpZY! z@qOaUfN$i)R&X8M@n5FoYqjk(o7I2z({0$W|HCj|AB@A(iB1e~K7rRCsCGbfdJhC z{MX`7x+ZxH6Prc};dY;i>Z3ITpp_Jbyn1sAmDegu4B1%wUDAmIvv;2k`pqK;V#~ke z%@X6j8G`MB%e`pbzhrVQ{w3er)l4~5RSS+8aHTzzF#hl_`2pj@=WA(5Y6UBtT3GF| z!hgxDS`oNZK{95-QxSI@snH|;OCE5m1JeFf+WohwWMIu-^~Rs_L#Gzw9j}-8ltx4D zZ^!!6#MuY}Nic;t)>CW2hSJO3@7vI^x)Y8)blk`{Z~03_I1dA3YvV;msL3L2^R$eA z`j36?#w}tKC*1fyys&0|_hiOl6*qXliJjD=>vQL&{gl6$L1X8MM1!x%^37et;3rWb z+Bpy4r4mfU^R`Bp#h3rr_%<9>r7Ai{c9?MT5XjOl;C{;g#Cz0(cWR+o5pkFpl@FSQ z>tfZkhf&#?Z-Oz@6vzCZ&NEZV7!kB3w3-d zPGutap%L~eI%Q1u!Q^*j64!dL{q%RkXreVc&)Ao9W(L5)CITU@3>pFPfjZKECj?C= z=+ScFB~WNbK~Sm#^a0n7c0+{TfTUJieAdY<__ax!R@2ClIJLoqs7&0N{Xsd3XmgZX z+NdE|3#W+U|2AP8MZN+2>2D2XXHcf?w%Pe3!$S!n?fFk}U`Dg%fC^eu0YorTZIqa7 z>}hl3NmOAJ4d1RPJf_%j7`~R}r7p=sG?w=Nj`j3-!PIUxg}V&xK(V)4)v@qX=ACI` z4(T5r{FcDvy5_kQzs7clun06dD0H`n$Rm?dcBg`Zqa8NXdJcsZ*3>LkZ90$i&4EasmXNh7$$oT*1O(BiPPb(bS%MCo};{cM{eu5h}kvuLkaR`8<#kz zzlk@}*3+-W#V<>6*6JmM`@gEiWsm`|Y=JO?jxZm;Hv9thF$w7?KfiT9g`+t>&gsTF zgFBG7`pF#_rU3Peb}NH;@%-f0Wg{{n{!0XRT`pj>|5vly=v6&<{ZsyWB5M|b$b1-B zo@+YkF^m6S_rJ78pWP7ImmXHT7(3_KY5d8*mKW5Xx!^xHO&`U7{Y^u-H}u!-g`X@* zLPVMg7GLy+YuDS#c05;9`cPd(O2M0O>GjLN*NGfu=n55CxAU(YfV?k_^Ea9uoXrW& zTw#jhq0)ESWE|ZUeg*6U*$$VV{%igcBFIZNgjGvk$wrJrASgO|5+8TOcx(&>x3+^` zTK9^ZMC4dz6kU;g7^t>13~3QHC19tvd_FOT5sQ z!gwR|l=ZMLvGlt8gIpDc-aRZ^ybDKn_L2%uZi$%3H2SR>a!&BjAe9iQI;S#zu9&RI z*q-v$%#OHP&t#pr%a1?x;WZcXv(Z6;_n8-fYe*QWe!uIGhU{O;}n{mI{- z@kaDZm_s=0Y7+!n1q#hLF{=Tucwlms?tAsKs z`4i9SkJw|Ge3DEFjTPa!7;fGqwD`)JToDTB+0bKM6eq0Y0KMI8vli7JSG4Agr_>; zmWPdFNHEXR&v>mg8Xxo6V6oZ`$yiN#&f54hUVny)F?7C3ZbOTT5)f6vN&U+{>I2S5 zV%J|1n~V!y=GF@s|F3;+_xZSOAlfcowrWDj6CJwX{~ggMOvl(|LM_>bvl@c;lkYUD ztxATBMj&|5YN7f$fE52PUqNusFx6%f>vfNaorrH!x&T6kEe!;XT0h)6nHyjmSAOzU z)!p07(#~2{7-h<>+gqhU$m#K154WcV#Ea*P*njKbC*OX?AFWziJ_)y&Z`KPn=o^os_MV+NDwC9idZ_Vf7%A6 z9t){0{`|HVx8qa1&NCW&hB3*pz+?n(^#8@PwjCY9d*I@V5191D9_dbW3bp#IJa56n zC7V`Yr6aEHC!Q>Hq(%}S!DIW;XkRm;>`VVIo(Nqn%HK_zh+Qt8!rxN*0QdfL##K8g z=HtrzPKDtpLjS_EFe-B%Q`X>|`{Ho@%~L1-UwA}8`xyI!>U(=KHiv|A;#>&KZ984# zPD5=OxjxZeP4xUrpU66KFLp#)L^}6KD8w(+r6}HtuLLMdZQRRg-Z+Sj;}oJDs^%Lo zY7Sio(^%i)OGiVz?|G*Sgib;S#Jsr}li6SI6L|RoU^Cvq?SWw&1?to_JnDRe_8C5z zeoIvHWO(3FzhAeITYp8_R^DJ!KO%9NX;>=T_)qZA0Vx@Jdu%*9cs z=qnC@d}6kcQt{h+5r52iTY@s3Kk*z13^Kf(Ir_pNTB2im*#Vq?1I`!1ywjUn_I_eS zzE!_fRnF_|UQKICnz5841XPg0ht_ig&fjjSO-}tr(TL&`FGcaJ$`304d>Z~-oV}T2 zE)+CyU%va7yd!r}%Xg%UqnF+h99|DVi8Y~i#X z^a^>dc|>X9ULR#6n@g*fb#UrpVb@Fkm%V6uhpv8cT4?$$dmN^;i)5JGZKE>$^?=Pr z%k$}a=u$v?Z^t#h@_zRx*VkZ;WmLUs!-iK$0jSn zwyuX&AzrB6k2g^^{G#E+jmP;7|HI+?u87}A&FnyHC>70Iu~(}Ogr;z22to@)+^^{? z%z*QI!2jRL18FxgO$75FC3C+I_}%sa=l6i}W<){d&yJcUI82;Vno8$;|B~0#?rq|2 z=~@A+&~K`R;%EPtKP?pH;7Y?&!D>xB{OxsZIDq4089~ljL1j;)(5e}!i!0r?=Vn);d=aX!BVQuidmHx{@fp-Ov#!%D-pj+~Ppq>~TmuO~e?&u0^A z4!!~U>g>JM;J^GGlQF9N^%Er(`875Dn6v@@9>qL<{NOj@pb%*2lOXa0;QytbZXHP| zrc;mW?L$Yl^=z7uS%-qNh@gcX5j2RxMO?3PMBre)!r+^k(DIp@jj3R~vg+BnHf@t$ z^WO@|x|=+1^2AHRV%MPxQXuIfoBa6;0E+VVyVrFAu4j!W(sUDuwnp$pi%GZ?$hT_R$< zVjdMqmK)0e)jEwz+muUyD!WN7G6*7-1;3~mWGyskC#L%Eq#Y9L2Y$~`cPyIUs${z7 zu3YzG$7#;T<_xCCAOoZ3*MOL_{sEP(qPWM7dmeh-G+V+z#W2sHy~)C1ZxCr}R3~Ss zDJspWhEpO3&8JVcgaa3Tof08Y=sN7}V@mld<2mK5U(K60F}UC1JkbW+`=mX~Cr9W- zF5BJkn5Bnjzjh3xUuNX2Z+lkTex7v-9qH9gxagI&6-j0&+Ts%J&}>z@?dO1gl=U|RYwS@#WQ8oF`bm@wc#+kT2RP3l{(QjOX0RbJ0cXg1fy#4dg#PzH za(4J=Gd@UpfYqCQjhc$6hZEJue&*1|zG>F-Ndm?g!hAOM~_3 zVZkMIwyvQ&#+!o7^&89*b9Zwvh$4DNGV1J!cSTH|WT@94o&+Om30!3M7-9y_7|L`a z@KN67?TjBMN2Ai}Sq+mrywm&w`CxA)CQb5)I+12h3Az}MDD2I#_()xC%`|159Gh>S z3UOv}Q58i+?+yC8z8Su)PTF>_0$hAvs@NV!`JUP`L9*gxa!@M|=JFCk&WACz!x&2Y zRvl|JpX+}!cKErtEMKm0cbbXfXZ<{!XnSiBi1gO)AV~$_u4`W?cTr3V+n~o*{`gYv z#?yL14IPQCG2zkNIO&OuqK8uHkgB_%|p07%~g!zkxf-WV& zZ!|d$c4X@+*A^NgGF0$z(Q+!nuy4lm3ex|Ed3@%Nk(01ekuYtP`a0y;v;5uv|Dm(C z+U}n+QMkZ&-3F_JrhO(>e)3cFzGGK5rPL_qTB;^b;pip` zRrFUP<$a1qKvG;u5{{@QKaiGdFl)qbBF90O<*ja_m_*9l`-=F)cG#<}noh{8_i<$d zsTDZ!fLdfFDCOeFDAnr@6iqn7RRMC{!s>f)8XG^@v9kYpGF}!5CG|S>-LcB);;6*R zs;#RDtV6uGI`&RGHRXx3&>`>MI`fdGk!sg)V1iK@9W~5E{l%Lzqg`ZqE>zHlk_eSD%v4lDWZil(6Cqd8 zwqp%=!$bs}S;$Rk$^2n#_7316rck3V!=Vm`AC66k2ztkX&0gYqTn?f}x+56HO#)EY z%pp+bClD^Ny%C}L^Qgi!@}}hBEzqbB;Kcb#7LrV}{A#?$oYqiXWDO}*yyO$DcC%tX zCBOz#9E;%{|7gJOwx)2TnIaJWfa@{qR(pm?qWc~8 z7RV~QI0Hvv?g_*`wNaiG=K23|A*>kj>B*eYyR0F**pcI-{k7UgCA4yllb6-V(4a zPzvf@VnT4OsgAZeMHiH?R}q0L{}jaqOk_)lp_J|6|DSnT=&%cF>(9XWD93%!Z^015 z$Y7-B59ve3GiUUw=&!3Y;fa1qD2Ygr$3Q9yUpR3%r()eS5+dL16(hN+oz>vrpON?K z>%wEI8A!6NMp^MF^i&97WNh|~YrK}cZ3wxRXXo3xXF3~)wdxNt%E7yvDs!?*a}`Tj zc@*>sVuv7wv8C0cFcn)p|AFJ3l4(o04D3u@BZ#Mg`in5X_~yr9Uf`m!4_(Ks^k694 zVOew#=tZ=}E;k5kyMsQ;>%95Nwjt!p#E`HX(4R~jvlxNKok?IJcA43U{BT~imz*HJ zO@V?fO^+_4oAxpk1H59OiL&->DbV01x1~%s#bU(kNg^^tKV(Y>4dqjX@ z1eg@WRp&8QTj2G97O5zWlP|T>BBWId7Qz}zK~S7su>7J|hslA@)_B9E)FT&GmN`?suGI7nU zF(@ZXYVR%Rw0)9TQ~!4ozpo9I$&jxGBV^)5s&Xr|a+ z+_9x-qd!(x{_vg+pEqf9DIvgx~n#;<FASFkC5(d&~anW~B0oS4iA|bRM?KLWK7x)}3s-wr9!Foty z&{&!YD+C>u0wKQ^h*&2)@OjS8UOB-(itV3;Ckc)t%LeEkB1AnV+A;MIL};E0=a#kW zzuaW6giftegpC=9jGFB&a2d{lZz*CUBjQ4~Xv8=}$Se~0z)K&H0bNq3uQ6Y^JCn}~ zzQSTba)1Oo*nk~%Z^h`^N%3{ZV-EFgql|xQjD$VJUu*ZWfC$#_5H;!6=-f)XmKSQw z3DUM*L>hI_+AlTsjmCl{e;{{&7&O_81u+fsrf;ZEw=<8&>WZ5*;w^&s%}FLq-xcak zm|E85!basW;vfvq2`0;?n=pR&ROKiJ2J_hf0}Ud`Xsvx$Q@XhhKjR=-%ajM&&Bh1O zBbGp%I#oU&UN}*DTvZy;gMyrvMk|v75&(wZQS@uIPBiItK?Z^K4(-}S6zULdZ2Iqu&)8y_ z^D;;Dx~US+HHzE>WNEKUXso&EZqfuPHcx|7fB-n+A9nN#)V7I7fy|LD?Y9_)-C$}s`HkJBxDT8RZdLX>^fAnbib)=_AXG(xg7-L9FHu;UQ~WmH z1si<;IQ~SyxD(X#ApUMC#!Jl?G1ye-rPo>+{@G%9Gy%|`9NPuidsVLzX7qF5`Ljks z!0{U`)NM6Cn~lX(a@}bX>}v>vsv!s^X|3noiR&#gusyqp7L|?9Nvv%<@P?#J7Q=U?_N`(3@7dn>|zC$^Qyz|jwKiQNaSDsR}@E^cMoRD zPAcH6qR|pFfd15u@tu-X75aimykZL~BH;r1Cp@ehta$94)lO|#!-Tt(`)N4hza_WXHd9S0R$ zCVn@bM|HHQUlqeGQL^wlis6Tp?u6hW+#i3JFnE?IGB0|)9)lX1V$23h&M$oT_h-ui z=BKZ1gIX7#Ekf;aR&;+;CPxN8zQc&%AK)#k$Xa`B&eo;CmKO^$A3+x)eEB6=ACB8m z^rPtm7C6TacyLH&m+QkEz(QC|GES5j3hniR!VX2EF;VF;2pheYNAMd|`*DEzsS6~K zX%`kY7H{xJ{$xKVCCRcZu>sP1Z4>-#R@#G^_YZA4Ex5jFlX^JPmaDJrDB^>(Q#iR7 zN=LPJ=()t&F!P@-MDN3=v|P?o6RNoc(bu+y+AcDYz@p5{tg$~=>ITyxeg_F_yC{n! z+6H^q=OTIp56F>3)95D;jH#$_P7Q!fe z@FCW_HJIG-O1aK(bSeQ)fqv2-=}rQyU~v3i>aexqds+_TA$6VB*tynDxiHAAk#nlK zejW`@{7)DeEm!7Smbc&=6P5aj#0=ZU#NLLrpx1t5PCl7e*P{t7zmsnx+11y_a-v$9 zq9(+NgI91yy{NQZa>7zCUB77~SRdJwnRtFA3irIo^UZefPGtzM@=_vbL6O!Uk*&}` z{QgQV-sPU$NM291n%m4@K$b2tK2U0tOf^rpVP`OCvifo3VTy#uSWTqxMgo&H+$~ES z%us)2T4di~S1+ci1`^bVi>2`KS(Tt;qW)7z`+lE3Kq_T{_i1Sv5AnQ@SUGpBl@IpG z2!pNLKf&sYYNKNq8Mq591WtCq5vPVGtzDLi3}mvE!`(6F20>_IiYjIXt7lVHbY5@( z1)iXi&w{HWpCaH2j1TDVjH{d-4%};WhIa7Qn_EDg-~eG#Ezn~3XRmDEO-SdR&ng*P5i(lYutDZZ(P6%$q8+P7*1M*mXun*DaCVF z&|X4=dmw`5rx>-Rm-V-oh~W_xTeKP6TPCL%ts?&**a+QI?v3FED&&j?gW_;aF3>sz zw!I=77M-8vJen14(&o=FHESDpxefhi2a=v- zf}T84hMy_J>fNadj#S@f|G)Cq=9mGSyF}tdn`b9g&!$%pNzMdyiuR}iL6Mi0)Rse< zixK6bM}b_aeN*YxT7fViB~cos3_A6z^yQi+?sxb97rGruRzksGt0XNkw>A#G4PP=* zq!?4a6LdOm9z8Tk4VuNiROneN`BvFOSp1W)S9trr*p|&3L{(bo`mvMHsG(BG@*Sl} zjKb#xPi@#>ZBx_!4%Hj->WI#kY*X3LkN}tU*m)>qKYcddQd_!u8}}RIIIw|2_lHfr znL(JAGB~kO5s2aJ8(Hu%GvrD-Jnj;?&JPDfP(6fX{8$*;@LlUTGE9Ru!>#1(UWoYH z$E|;CNK9iX+s+9yGf-e2HgF@zlUWqh1*Tv{8tG1>vs;|1bF|=2UVr#Zv%5*k!XJ!G zbFLS;6A-_E9703hL^>>ck5FnkdAxqEgE>a^g@DU}*toP~@j!_bad)AKtp(P}O~i@8 z6Ln@gul3E}5{OOW+xNP&2;|MODZdczdq~1llAf`$F7g-Wp|uD|TT1C&ASc(m)V-?X%!_B5zo;X# zJnT^5Ls)+*H#=v172}#oD+&x|!Er>5p)7S6VeqG+U}!?E(OfUeO#Gy~qm*iQGHAAM z2yv7a+a&Io#07e6@r6YKyOrw0h_(%BHBrnkm&ePFiH{ZAOh7-nOj+lC5Vox&3Gn|b zzPlPxb;-hgRRM|o4WGGU#_r23Gc#yH}%hdnOtTa z`hdc1Q9K|qCmob1t!Kz@P5mUAPiKiFrwHNUC=T`WotBX;*s|_39P!F^uQqZ?pb7Sz z%798)5&v`y6ATG~GNlE&E*JERhGq6P_y5Ta>V_%}Eb5nK+lBSSA!{SO^Z6*wM7^~-JPhRQ>#ib8Oa9+E!Q>oc@eiSiWTUhEuLWof}BOT5N}^U8QD^n#P0u{ z`~yqDURyB&?fV0XfltWbG|SyM0uIOt2-}M+IC~mv$Az0bTc1jMszo0}$t^ST-%``d@3a~dN(LH8Xr8H$3 zT;ZJ@5{$u^))gQ08Zt=;gEBm6Yn={n` zov5qA19fDpPro=b#g63}mU%U_;349KiMsvtaIGNzu7Uc^A04Vybm-m`g|n)Lm^pp4 zTZ)ZKqMGRZs>l@+bu8b`%6r8FYRyv{s=>Plfqd5nE>|_u^Z85PyxKXZkB>vAiGSqy zqDZ1b$+zy|-EgbNbwO}pcU?JC6zyv64+;@N?lc)8YB%&yZCL3%doHuEh;dGF#JDA& z2-nrmKjAK?uG9aRbG#8M98j(R$BEEj9_i%D0d0EQl3}J1aM_b>R4RP5T|{lh%*bE1 zL-N#i@w>?_YM9ilZcyH6fGTFC%3b~B0+r;oxDVD*aP90dMyw{tJm1_I7ICf(@!gqA zOfeQudX@!_Z8WEifTmQF{Sw#f|IGp@N1N#wSweaT%c)*i zyzdWCaW$2?9?<((G#Hbkx!Y+DhVG zYco#AunbgB+2g@lLUK3=vS!@P(D&g-qze$$XJ~@oU@KD+*~%pxmGK^F!-l|P{zFc% zB1KcRAwMsZ{eW6tM{&L40waWLdZt!~AQb0q+EkDgw@r;GW=}wM=I^S3bH)+a4{a~it>CmQP+*NQJ9_~g@u{6 zqJBz;a?`aC62L0ZrxeXW}EII&H8p57I#Ad zQVIbM+NSi9Vq}otGA#I7@C;sr0`nKHDeiNQxj!kbQ_}+(J2{Wgehr>Br^TFsWRcsn zU<)anKdd22#86Vz=PaSSZFfHRzIQdU6W?(SVr}4#hq0s)%{*5VzS9NBpNqfnv0b)-3Wb$G0c5toDO5nR`Q3T>gNyG z4gy|CO`X9%OyG4-r%dKoP;22ONx)qceolNH2XMTKTpN<_;a8@PO9bjgHpUocgJe;E zI=K4N;ms0kU@*(RoYPYWaIHt5xSAbofBzY2_Zs~_&BgbBm_cGHhQsbb2pGA(9{H7% z9i8C#xbFGB7a9}tOv~^b`&m`4VY2&S^QK0S{Bf-9i!(+}rk(sY)BQX$tz+?!H2cJ- z>uP172O_o3LmD%2c*}5|I_Y3#`L*X5$lXZ4%KpKR>KBr)7w0!8eJhX3U!kyLa7Y$} z3e7y(TV%@`5!^LU)ZXEIUT>(-AVAVb|0nLZwUc4mb!M?~7+Kj`UV4zMozQ_DC1+Bi z)@ekfD(E5eV3QkpkFU?S;>7hxsII$*`mJ~B zPT3i_A3nR4Ratqxg?`6yZpHtv@~jG@1){GV4OemJYO`Vach4$K-s~2-OV73`5PzPL zZ1eU{E98!%fuy*vh?J>e@tjj_l%0R~x!L!e*dkR!V+8ME5Urzi1^-{Jx2v21;d4?D zvx+EveuS|CkM5fO@Qx^=fj7HDA&lK4PQH;m>N1D>!T!}YZKZI;w2R1RiqW^1vsiv# zy^LTSBE#ZGAxz4+`R-Dn4P18el~T=*uSX}J&w)KP9Q9^mS3ESTXxY;5D47P#*0kV& z#!#S-^_Kp>ngcMI|EcEAxJ*TF;|nH*-R z*u0A5PBoVy>K^K)=LLk~E_c@qppPbPFub^-?l;NK3!YWh5C%X%SyI^7dpuaX-&Ea1 z(XNGm#vkQFi?IC3*-2@-TZV4-H46s;nLGT%hN@%8y*>NQ0gGgw zn`#v@?MvpIQ}U#Z997YdUSLRq|oeF6ACX%<>!uE}Um+DoI;tEOH5w zkJ%NYEOv6eki~e7{4&YC$dU2p3S4`ZXvs-JVP&NP$pO=_|5@DqxX?$OsGbz+QaeX< ztpvo=ndbMY9SAXX{hm;C1b^!rOpM|qq!OII%44H2qKPjqq^L@^YY@4t5lLmLgGv}H zh3_=ByCMwXe6}5v8Li59)o;M>Khep098jq$_QSZCxH+A#9BAAMn=FSqWD z!U}ySzqqd?tka1%sgbPwSvDpaW>n&xOgU)98lezlcO4D7|%Gi z_T?11t1|hKd6@+wvUs#h(t{JtXSeIaYUS$IHuBPq>NOQ{EDcw^c>pO8N>2zVkCf8y#7dkQbkTaCB0J7|yXY-Xg_->< z>1rwE8NKfxeWzPq8PHDPH|f|`q@*^Y8hPj-Ax^oecitdVKbt=O=N#HFNFcSs7?%l{{Cz`>12Ol(iw{m9sGm9JBsmYoe7QB zNy;(fo3Zo>vvL&APNQ(KYN40{s1HzHxT-gR0mS#|;8AKL`<^%&P#&;9xFp67MA%;| z{8${6mgV4j%Fc_+zk(rV5uk2HSAQQ#0><-tjZA38l}`Frue#Z7tt1w(|A6vvA;%j5 zg<8a4hiQ#ngHG}5z`u6 zId=@<{zS8Kl@80l&nR$p6U8SByRHW+yL5g613X{Uoz(P_&;CSd!b{4$bI>~SFL~Xy zw`;e-+Jr;`RRnaG2tc(T~ zBDl{at`;R#j8UPR9g%X_o?0xH0(qGhR8d>8x?kJYPX1ejem-2%XJr}vIA}7Gw}>`W zx`A|l)2_g%iL)P1cRX@vu-pm+1QGsrhhGz#I&g}6J-R!n@T(**GA+DG zIi_pH0MbE;Kg7hVi`_}ot6kykH&sUK1&W!Ium6KMXvxR!uDgNwM+|?TuLtR9u1OeE zUThaUQ3W4N3Osras8w7ps>@wDI{cs8?SkGSy_<7>DXNl}pD+&*I94c$h;`F_-T}-; zl9-zGn9P0|$^|*o@&xyk9(7xEBFWOF5efp(E1_96dHk!r-my=yhWC+2t495=h`+uXHlHQOKA%c)>dcmSUiXUx0sWS%G!!d10 zAG|IhGFK&eqIGPvj)Qy-t*e=yETyU8yT1b5C;|h9?%wrDc(~aKqN1uteaI?ppfWCVHZkY_{BPJWk_MaqO}n zRr|rs3=x`ozhpaXmD~eez&9f#DuTUk>HvxZs6-ez5!>f%xWPmj@2{GoRNadqMDL(& zr9T7<$8(3@P#I|A_>YVx&h)?jbYl8n6U8q3t+%Ry&;k$V$jib*kbG`sGreyI(-WJ2 zm(&0kokV7KzKYj^#?w(o7ev(k?YUp`pz|4zA>&pAM*{703T!HUReTL=z{wOU(oIu& z6rlE|j{{}7IpV3x%iSEP5cOAm%Ps(026xiO#3MJe$<3F$EaD};6MXUxQReML@FM3p z@WEVN^7Z(GlyS5bADhbG;(ti2E>bSLEp>9&OSd*~P36FhZf!waa}~FY{)&y4&L_{- zDgxucCClJtvzB8sY2_Yf();H#oLtRxLga(S0!0)HtT+!jr9_7&qZa0(;Fbsj*~1;& zu2KyMM9hb?&&LOR@GA?Ajxiw6;jc3}#4?ThzTyun+ZahdMrC9$65Sv3sobNa&tMYA zi#OT8J0T=%)3$#H_+6W#9vXRZYRmVY>2mcK)qtmGk_}}CWULL1kvt{Ae!rLz!SkOw zB?7G*9B!B{Gd$B!yqA+~Q2sxqqvC%8X zFqm647^4zrq`;CBHHl@~7JpoPxs>K#ws=dlBKJ&$oZxj!oCEujwFFaczE${WXCAH& z#=l3tLk)|}PpmjB`-Nawn*_|x(O1N!Zz=@)N? z2V87}-7tI=dqId#Vm}^zs}9RIj@wSq3W4Qpz?|U_HKe`Sd*0NSCLVMZYb~MEld_@J zFZMuqXDHh&RcCOq&hmPiG?Sz2B|NBCQ`ad^{z)XnPM^x!pV`wZkdTjbZTQEcho`?L zor(s;HJ7JP#OI42x=oVo6+H`&->XHxp@e48*@GZFcKX)Ub@aUui1i>pJIb44x)o)M z_B5h5Lu&t+cTnM8&^i`6|6eF@qy!9nuVeqRYh?)@D%k*jl?-n)v zE=*C}NkR$P4YYw~KpWpz_dRS02w&gHA++QWkQ)0OX25Ca-(Rh~Ql`@+8!g)1mDbRd zei>6-1&DnmoG};SodUgu4sR7fb!XFW9I-7i^x1`Mb&rkc@Tkpy^kcJND%Yy9e)9B# z#Y3K+@15!HAqZZ>UAhHb;8XS_aXLsEoW`OM>SPbnIr#Lb?BXOdx3p!sVNhj)EpLQN3;9p0dmj5|uTnVdX%6;W)P17;v}T5{KA`=LA`7N#6(-%c z>%OUP{saOj7My=ec>MIlVIA|5J>m*vI z>UK5D3($i-;RtJ}ixks{)8(f@ACELS^XqWy+Jxs}IzS!m`MEGud=6bCOuQ!a=aoOa zPH*`U>RB7`zP?l5vLu__-L?l4C26w-j*Gg?D&Lb*ay8;T`=n1W`iQO)*?bJLC3C$9 ze7h8>%nt0PiwDtdZYsuGcCz$22HD=8VRC1SH-3(#;P-SL?;tc-@{j!zXywQs>h#vf z*A$&em1I1YFE9G}(ZGOiUm%OSs118+2LBAau~e)%e{N43WESt&;|zxvQ>O*2rkTfo zn@Rxs%1|bhk^!gu+!qw?xu$UXq@JLSKhGM5yMe?OzmPGAD z(Yh{W4-Ww+PP;^1qmq(S6%}}X?7VzjG6^@EuvG&mhqPqQm-sOpGdr(pUb_@~FG_2q zy6V$#K8NCqaNj8Wuk}HHFs_f9HF@X_20f(KzIgg=f<3RW{htC5>@qXfX_3 z&l#~BH}daJqeH)AyuHcyp*zx)FxRghImhN9L7`xd9QU5T?IRT#`?fkOGWbxhCo9|h zHm&4hm?r^xxD{Fn+q8qh$Y$TICz#DKd8e_73L%9TixJ-j!iWq(6f}3Srm4WR?Z-`* z6_)oL7*d5sakuyd1!|t|6Kx)L)edBhw>!q4OvB~f!x0=>exk)zQP`5s>&tMIsWg-p z=hiF@Rqpq!a3iVN4HIpo#&WiLB;ORs3jIrj(YeptKa;6nS%_yBWr4S3L$fPana1;a z#Mu>c%itSfGo)Hw#Qk^g$AIy95a#O|+?P1lL^=n$jrD?;InWB&=~op?nf}%m-|q=! z1{oBr-dQqxTbkB4@zZO%U|At~O63=ESH29Ub~N!aZ9vIQLHzW}IlXsj%w0bj)g!e+ zkguph*6Oo+AnYmq!4jLqsCnSp!uR5K?Gedb7x)fnZxXGU^Yefl_UBK+;dMWhY1zZ# zDQ%$vqqppxdS zG;`0Zm$iE6Vjg9RRo)wQN+o^ZK{^d)_=AH#L`!m0_}k$@IOY-_XXBFj)#i=M;n?@2 zpw10!Xme$N({m3k(KXgRJG)vXQfuWBMZ?`;mE%TKrnjq$w~4tl0Kz-FhGm|5>y~w` zVZns5my7`JfQH^FqaI=~lv6mo%vbNxhce(f9!>rpN+^Cwb2|!d_Crp6fSy4ye!Wdb ziOGNy>LuwWv9Z)_n4@Y=`_wwiNxs)(%$gS^5A$b;06skoP18*<{G=X{UiuPg#0myE zy^+)V(FE4f)aw8gW`(cTuEhZ@4EPmyNn7lAT@2<@+t<$ zn(Y=e%3PM_N<&BiPOrXSb z53w257f?B!fj1O-ikw4;roT|7fAJw>EhohQ?Vm+Ernv ziJUfBIzK>k)3pLf4SzkDRtcxaBj>+%;Y|Qn!u`8wC`xk#N zet_!+<-TX*#a;~OY03rw^0$TQ!9vB@9NU|qOsw#s->?F<%wCCGzbpq)vSsvds2HE@ z@@R%sMtOrtTI#M&OS0Y5s2wCCR}N}^1b&cEJVKNJXc)-M0$Pop1& zb0tE>R!LWOAY_AWpS8c;s-fPr{SKx!rY!q+zbWSXs#U!nzFSv3P3$Pl z#l0))>}-_FKFp9efA6^kQ&g%XKW=i641w(RS< zEig7erMXn>{)>N9Zj{Y`E4_vJCy6AZM$jI>EOI5&jmcc+geo3o*V2yx`6rb?O-If} zs#^5|i)NzTcgm{x#w2&{>o32tVN^A&i5uTI+1nT?d+1y$sF*m4O!Y7R{ifOsh3egq ztn3l9gd`>w1JpMkNeVWObZ46dSM1eRp<#Gls|(LX$P*FC5W5?35+er4zjhGWF2?O{ z9syz%3f+WKc0jxXD}dzn=pV2-{i<^MUPXGk1N>~x$)5Mi(D2*7DYNSV@upWy^i^PK z!{*3T8Zf+Q`)a4L_~m8y;g68}z;gK%nF5HnVznbiN&`GW`$%RJeLQmpAl_l!)?{l} zB}w_*9t3!c;Em;3L0ZEIDdfVME{))76KQ~W)3dY|`%r&Rzu_zYG6A|k6eK#DbELqf zM?=W{CVAl&)-i5$Vm&8FBSn8)w=0<8{TJSOxn}1U=*UpVu~NJDYu1mr-hC>{v3Ht2 z#-8zJv|@^Yc<1~vAGpz+wbpz4!%BeG`3Ddm`ESsypUkr-3V68}zC{PG|HAvZ2az|a zox~-`u3;IM4lfi?A0XZsZxIVeDiSqaR{E5_xBZ2?6~XNZ2s3rq0%?s0=63t3Tmb?0Kk|ndGE(O-P(If*jx?$% zU#Z@qSL`x+wHb&k$jD5Xx&pT41vcj)bx!#zYKnbzsfJK>p)qH@yEYdzi~)1>Iw0St z8(}FHme@?nMp)VpsM@-k?|YkkNfv89t-UI<)D36>`L6c_JaVG0R}Nb&+K~Uaxr*aQ zdX4Eh(>x4@yXj3TqF_!P_e!Sfg33n}z450uYT{pfC)6AvPjJk^6i5Q1%Yx_uQT*`&J`58-)k+XFh=SFWwO@pdNk5xPOjMM$0d4e8PAa_#ay2)i< zdntxWTcSc{jjQ6n;=Kj0OYgs=P7yJ}Ddk`;p9&c7&WdX7cJl>BU8DHI277n+SrCUU z55FqZCFzbF}KXbV$}G#&R_4;v64z}FTs7vE*-DUK_0T6Mzv+yln@ z-7gWx1HUy-$U|q4l2B=jJQtUi>C~ali3y6)VxdHIRgI3I+gP1rh798yXdd+XU-8B+ zd>_N=&(!!K-oh)X>#LOH{S8Jt@!OQ-Ro&+gQsFXSyg5I2Hmflqm^;b|Q-iVg(D7ZB zi`U-->adr^sS(Y^&Ckb!b1+s{RsMD`ov)Zlul_5)FyqX(zrhunnyDW*ydP=D1L_0J zFXu zDK!mY&H{5syKp}{?-0HomH*;VNcYaRW|=UgE@q^IQTo*V*srn%Vd7(%&+)g?f03f zT>SV>aJ-?9GWe<18rI^Qm!iLN!DMR-#8VN4 zqCCom>zkRFV{CGIYGc7#Ztkx^0{cqQAA)mMHK&XDFbeY?i_tk*C15COHOP2*R98aq8BU+7u#qvtTv^Nk`ufOSwVd z>uFFo9u2hHX4JK!Ivq|58RKzPR&Bx1B@I(-oOh9MSw)E&Ba*|knOR7v`U^|jT?#D> zZQT)DK*%EmD3h5^4a_2*nlA-XP^t7)h0Yy(bAU?Fa^pk9+tZi&rr2Ixy~onEJ9i{a z`*=1hgXq_8u0Yi@U0+wJt|_U_!%!3*VEtOmO!jRzw>STJG-4kVXoF+G``YDx98H35 z0yC!hMta1O$wGQk5pNJZ@!yGFH>?*xf!DY}4Eq+DnACB|leG}Vf=?C>kJgVlp<$Oh z2!W-bn#Sz!%9l(y6?bpN4Qs`S7q73LZfVsxe=b_?JCv5I2V>a+HwTFw(-%YD-K77Z zc!bYNV~SPs6<%*4yiAMiPI2^N>fC$lR!3SwvHRA z52PK}EgUk9rvnqgGXo8{pRSh=o|ow}Mm|)I5^)5+{e9HFZUwA$r#f%_j2CZvRzD0o z2`7%!+5n8gv3UWeP)Ap*%4Nvp<_+(C66DfIX}jL^EVvCOvN!(e@VyA)TOgulG*__c4MMK*`7$qik)-#uJk^?j{cS4r1dF62dAUta3i5Aqg2G(kY5E8lcD zXYqvI4083M4Nz1(VVQ4&48E|1)IrvvM+9^sT+;4(sRkB4)}hYcOEdR zhMULIBu?gFAxdgq_bPM~4B0)in4oMnSLrg5Gw{Ne*`!j0Ak3^R<p-`QL{3E zDZ~`zfy*P@U-Iqk>)60Mgre`&<|EW*2*k5lRxR!;%yc-__C&6pq}&yF%Ve&FyZSWL za(N9!$UWX7hlQ;IJ2@Mkoeyl#vj|6ba$q3cN!D6SAvgx3UB!XQZ z>Z#~Z?u}BEE~eK~G=2`7ci^>v!(fmC5gUTU2%h@Z(Ztonyr?yz7sSo?;^X^}aueNk!EBQM)ds=e*dTlw9?j`8R7{Wpr; z)QMT*sGI8Do#$siv!s5-s5+dn^qGxI&S+PR@fTyl-$?vDA5%SJm<^XVAaffw?^Qw6 zT1q|k1+MCwtOKuz+kxR3)~f;$j3r#8&bH%w^x-{C;@~7mu<2G(r7$d|zi%vt~gSb!da@f zgf#Bxi3~yU?PRU7$Uy6`aUudqxe}w?Dc)TeP0?__g9O}aLI-R-qud0kmgg7MoC(-g zIb&qwbf=7j#&&^s1>N`P!<-~lR4_;nskQo_bc5sCV4uNssJNL0%?fZM^llM=-wp%Ekr&eG`t3zE1$WKf^q1~LvTNo};=9x>T#0$jY8 zdH_tLbFpLB8f@a^L-NRf+RG0Yw2b1q&-o#6D8BTu6-fa@dP*GE&3%-wzw$n)6`O!Z zJwcW+^944!9XUHU_5Q^1T)ko=@P?#cljxn1Vt11xYMwZeb+1qwy;&{cy=ff=o(`v> zMopE%scze}IW*6C_B-441=9xNqED3dP;sU5eYr-QC@x zcyZknhvM#595z;pyStn|-uu6t+?SKwanyWp%OrQVS$zjx86`1k{rKlJ%AzRs(^JJRMeg2*16>;*;tTb~MdE%q-CxQNJ^AqUmnO2^J; zd#6F26%uzOd3mOer62iBVDFm3%w1c01P;D9nN|ku9;p_1k0p4`*NV(ug z+VErFJU7lfd^zSMZ(d55C zBEIzUS6_DBIAv12aO562E0SIlw$IY3vLk)vX*>I@j`id(di0^9#II#iNfIkCkqV81 z1jwnR#@8{J1HQLuVRl$m&0Au3S=%ZX`^c7)O6c_RW06_K7cmO$;^PhT>Y~Q?tDqC2 zg@QjX=eyvUoiVWNibiA0!y2H`&|w})CAq4<&tve4>=+VeOCjelzO%ks6(_9D<+Ac< zsSF3Ztj@=?Qx*Gkhewc(_2INpwDme0O{Vz^6T5g9Ha(?Xb@6`Zh=qLw2^}xIlIEN0 z=8`|buU}*TBcjFH%p;j&0;t_N4(`nn6tZ)**v)tBh2KAB{;UGksrst7A`U>ZEtbk@9@H7PZB9b{owW3~ z3EzE@l9SeV?AkgeBQ!IYH-l%6%8%*YvUNg&rWm{GP`nqR{IIfhtEDc0-R^mM0fAkQ z2_lCg0ugu~eGoX~S58b28MHC->=$_=2Tm#v-ABjREA}XR<~TMcAjvEwxE)q4n~gz9 z4haZu{P}Qq)AO{ zl4*kRo*2LKoQFPmpK8B$amMMVnvlz$WG8CGmR9d$+CUAY^R{u1zOk5#YjPC7UeTqA zhf0WtzDsL6v``am!Z3^~ogDVJ!3XAc424N>ow{4+9{^1piADXrb~}6mN=(9Wrn)Yh z&idsgdM_)e+|G(7@RXegi@WISSbfR(y`e{v3QA$n=u@XBNrlqCsOvZN|9LP5UklXz zA)V)xwlhC1L0Tcw-O|mygY6`99g=50Q2=K;&wwN5yYi=#Et7sigKLO54g!p}kj3V5 z;iY>BiCp6 zv~oi?;z~;mZ09GG6VB8*g)pBfXq2mMp91umZ&CkD0XQ<+ALp5eA+=*C@cMG(r4PuHy>XHAn*cFRkN(?Q}>^J_6Hgk*L_qaH@JZuEUTmzc3=-)dt~saYg4z zsFJF#xHC4BIdz4nyOn*(p#*m`G--hjRHZ-N8}JsLVX)t1?ZTXandky4LjnhGOp8nd zdiW9}Geu@JB_~UFOw@KNkQqH|5qLZ`uR0XZr0>Zwi$1WumfKcwNy8(7kvPp#c7zhe zqgA2^Ccp~MQqJTF3UcjRydAsT?l)nDVzx6}Y^mB;-uBgFC}BPqGwOZmgOk6Iy+Fou zmnS1PnMoG#X;C`TAL->;-wWxYYemy{cXB|V*JOrtw4V(Np-U*JI*s`Q7heZs!m_)oGz*oE6v_# z(%nMBwHS97=Nqe|c@JGl#%TVZ75mymVGN4|xb?+lY)|pgRMBfPN}~V7gxf|d$-%@7 zVd<5gA_I*j(BJ?KSXxSTT-vA=#-6wbvDuPXbk*|puA^imOMmM)Iei1|pNF4~b;MaD z&7z{)ypH?TF2Lo*$}pesg7@`D?I_W_NJ+a&bJA=+?M1>_6!SMlah;*yqFhX=Ke)Xw z!_i(_*_ziHJdX(qEnKZ)8Cobcvy{M#<^ix&exyQ4({OV!v9ED8lYDtAr|pSwTmHku zH?xiWcTo`cWIx|niho#ot-V;p`s`5eHE8v-TN8sU8qfzB>zK5QZ0 zgt-yFmX)X!W|=O=cV_MTdWre-v`D-3TeZdK7}siz0u%fMuPuMp&Y?xrDzb_#v&Ny3 zhlE~`L?rv3nR$br z+DueB;-qrZd~m`qpIpF0$=(MQSGRHi!Q@J~KI!v!4W^W%a{@D-<`M2LLx$4j=Ff$=I8s5J}r?i%&3*{b5V5G()3$_Sjy>Lz?JK%b1)vc=QadgPs z)xa<`_0PkNcvYs~AKT3N?)mIAt|xiQ(0!qgtajJ=3Gn~$?LXegC5mPxaPt{6!DXW< z_KptPuF;zZ{YV-t=6fN&zzwxI%;d?USC)}N5vm-OE8Memjyq0wl8`3#@7THu4gWJ- zy_%^SuSJFR6FseRTBN|y?=VG~tl^G>9FIU}Zkv`(dIwRRR<+(-)e< zqDLt0kq_o%agJb1ofoc&b%idK241-T-j5At_!>GLSyx14MCr4%D+>l3erXo4p3o|j zuG_SnIHAIK5G)`n-kRlHhW}Py z-fr;8WS7f5gi+j3kPHfZMET;BO7_{QXr+=-dBIkG7wx-$OJ7u5!Mh4Ka9dg9b5W-#l(zQsZZR_ZrndPd`z8TMDMA&x6s1v2Dp)gX zaHR=qLN?I{P5bp|4(IMxrlSyUJ{l6$S7=fYwyb{twl;ciOsZI(ca~##^7G@;=8Z>< zQ^Rwhq%pK@ISfP}3$dGVzwr4o_dO5VCqH{A7&-?D)P*v;iyFLQP z?lu}w8}-gG)}3M^$IpkWhsdXeT{xgn7@>e4#-&(+}-r4EiTS+WD2J-}3(0h}4$qf{1A7mi}JL{h(q1HVzH_<5Jx4ypT~9BG({->H1Ijn|T8X+WYN?^s5xa zxLfP_CKC;K8WJA@?|2X6@@!ObtN8P%?vKCz;#ds)_&)6t66(!W`phjv?Hck?Eko3wWC)ypR0+9<8jd}pckCSLLKZ8bC zcZcJ1Y+K!)BU~S zt!PsMAYXW8Mh0L-Mmh5hx5DN7X_KMQ15Cqz3sEIEFqT7@pa>z!`Noh2x20063B%`F*W)HI!?KjKMhDED?7tvbDGveb z1B3j?!iv_do}&Amx~+?Hm!F5mPT6v-7q#fYpn0{R4o7O%s;WsYI{-G<<}C{+=SaWB zSECySjSi;l{oCuGZ*E5P?Mc5IN{H%!J)A%T9VQ$xu3Q-N9Ic#zZCfjQ*NhG7pgW;6 z*UF`B82bHy%m(S~b*^iWL4Sw0n`Ug>%UYf-|Q;6|!WxWbkhe-);nk%bqKwKHTf*j4Uv7zuwdwEaGMq)XmQM*H%n^ z8#Ukl)V$7alJF3w>Cz|pJmEp%_ED;oKk0|D45fC{;u;h>QthC{XV{~;rY*Sa{*_wL z3tXfQB~j&gr-x}QOt7`K$1?E@!FoOoEkk+9UaZUXDqrp~FG8j5op*YoQ8wB__pqH? zysthgzb+oUx{o2xoNARwk~+Ef%t%Ybcz)@i{)uMf<@`>LC&M;L7DN-Z+u#M(_N)=# zMQu3x$sJc459#PK!kgKhlA0Z9ADUqcAJk~bT=x19s>rS$Iv<~&C(oGGkxsVR4`_r# zWgU_Wo$adgNj>-37~$0yc)wCF;n{U6(|NyXpNqX{%04-5a?3A~FOyY!w8Gz6EHFbO zJ1rA@;+g5|n2MkQRd!{2<`Q-PV#H4UOpZ6!vs>;Hemsj{W2~^*nYJaxCTzOoL{jT| zW@0;&Vo9VdA9N)FZ(-f*L4FuHIk+w&hX#T39`Ds_Mu!jOdj*ILOuK`$^-ybgKj)g8 zqe=g2#dKeLOB0C(YgdBX$A2`4YPgOOc4#wDDoNsV@2g{A=oLuNlQRq>5fCHPBUf$L=pb~e&q7;*)Es9l8PVyptTFpZ( z1G|;_3DI|<)p}oSnWQs3Sk%s;osw90Tp=|zW$Z;(YC-@#t<)cB8dsF*xFjFQOFfDji$`)7VGo<~#I474HIjBmd~)FMpB zKg2>`;?*zN1EwxUo{7iC2vsA2_*343`DjyGCG4o`$~}4P-)m*+gWX0*3trlmVN~lX z%t|E=SRX8$_QuglP^IZiwGn?mo-aQRW8V_tJs<41FZ$SNQz;ZOebV!>*p%%5DGo{s z$@u4gVTbUD$<5_BR|kEMqA2P{pADaQaZE7yU@NgZ5krdlC1ac&Vfiqr`{(d= z7>FR`H)rwzkwsa!*HP|^q3~8fj_y-Jm+s!KK~hbuv^zypO5SAt zCUXfTz{VPc;?j3E=?`NHr2!qsiGOU2?~-GFOc_%1FI8pOS~Hc3OrcA9nRh`@iB_HF zUy;&(&e#7m7I8TAWUN6f+k-$;`YBK~%~z>lQ=X4k9LAueJ{@g`TyV%{C_J8$_)mbV z5yDBXXa3M!!_CsT;0OnF&N0p;l6+~C)$>TAX5Reyw}vGt@NJhXUM6Q%c)?=%A~EH< zdWi}~zpW|3h;p5bW2LJ=4nbM>#Iqn19!G~*d(TDRX9XMZ%Yv44mZ&wl%0I%s6Rq3$ zD`LQ&4?A7^;~WxU_iImRnjvV3jA;qflVRP$hqfH-Pm0mE@g`kBzfu({FlkRorNA+J zyk^B4@f@#+K#jjL!bVIy5!;Zn~L4 z)eZC=E_Bv@vHE_{v&_Q}pD2Ia`j`*3j)oZX$(e|)0X}iX>z31N--CTRZlf)TH1~+g z3(}N}U#8T{NzP8oeSP#qH|O3bj0QGx zkVlO;od>C;gcTtQ0@SWiF3AkVxZ9YZMIxIoDs6_-TY)_;BBe|jr@zVHin&ceJ5h+x ztV)bw+@>#p2=>qwQf6-~K5cMqIS({A8cUHjQeC)po77VxS6OHcm}1=H0k#fD<*lS8 ze;b6*jrSf}!9p7gf6`{$#+2W?bVyyoD^y z3%C3kFi$#S$6-+%!T3sZSw&v$Lv#>SRiWm+9 zKljB=ZseMzfeh2$P)w*SZ2homMm}jLW{Py^&p3@+N#~z6V4s~%_FbtSt4?7sGoYFMrS1I2qSNjdn>Z3~(hsG`1)l*kY^K<7UH-8I8 z8u;+fOy(Ay7^zg`aC`2p5g#bjjm+t*Kgz!QuqlNi;{XCM$G8#Wfdemvd(w(4W22@p zm7psvL2eQjv0P2(57-Qk)C=;~rFPaE9Q^R%026KIlFoM7)a@_NSZ^A=JF`{$nO^APf9{VFkjj|Px_~LJM`EjL$E5QAZ+yM2 zYQT1y7Ii~H;qX%c-9RqZRY d7Bt1z94=Cc#)h;@69{aowpS9Wlg76j`7b4A+V21W literal 0 HcmV?d00001 diff --git a/svupgrade/files/svupgrade.init b/svupgrade/files/svupgrade.init new file mode 100755 index 00000000..00fc984b --- /dev/null +++ b/svupgrade/files/svupgrade.init @@ -0,0 +1,37 @@ +#!/bin/sh /etc/rc.common + +START=50 +STOP=10 + +boot() { + if [[ -e "/lib/firmware/gd3x/gd3x.bin" ]]; then + /etc/init.d/svcontrol stop + /etc/init.d/event-handler stop + echo 1 > /sys/bus/i2c/devices/0-0011/fw_upgrade + echo 0 > /sys/bus/i2c/devices/0-0011/heat_end_temp + count=0 + while [[ "$count" -le "5" ]]; do + sleep 2 + stm32flash -a 0x22 /dev/i2c-0 + if [[ "$?" -eq 0 ]]; then + break + fi + done + if [[ "$count" -eq "5" ]]; then + /etc/init.d/svcontrol start + exit 1 + fi + sleep 1 + stm32flash -a 0x22 -o -S 0x8024000 /dev/i2c-0 + sleep 1 + stm32flash -a 0x22 -w /lib/firmware/gd3x/gd3x.bin -g 0x8024000 -S 0x8024000 /dev/i2c-0 + if [[ "$?" -eq 0 ]]; then + sleep 60 + rm /lib/firmware/gd3x/gd3x.bin + fi + echo 5 > /sys/bus/i2c/devices/0-0011/heat_end_temp + sync + /etc/init.d/svcontrol start + /etc/init.d/event-handler start + fi +} diff --git a/xl2tpd-ext/Makefile b/xl2tpd-ext/Makefile new file mode 100755 index 00000000..6040c1d3 --- /dev/null +++ b/xl2tpd-ext/Makefile @@ -0,0 +1,51 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=xl2tpd-ext +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/xl2tpd-ext + +include $(INCLUDE_DIR)/package.mk + +define Package/xl2tpd-ext + TITLE:=xl2tpd server additional scripts + SECTION:=net + CATEGORY:=Network + SUBMENU:=VPN + PKGARCH:=all +endef + +define Package/xl2tpd-ext/description + This package contains additional scripts and configuration files for xl2tpd +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/xl2tpd-ext/install + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/xl2tpd.init $(1)/etc/init.d/xl2tpd + + $(INSTALL_DIR) $(1)/etc/xl2tpd + $(INSTALL_BIN) ./files/l2tp-up $(1)/etc/xl2tpd/l2tp-up + $(INSTALL_BIN) ./files/l2tp-down $(1)/etc/xl2tpd/l2tp-down + $(CP) ./files/xl2tpd.conf $(1)/etc/xl2tpd/xl2tpd.conf + + $(INSTALL_DIR) $(1)/etc/ppp + $(CP) ./files/options.xl2tpd $(1)/etc/ppp/options.xl2tpd + + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/xl2tpd.config $(1)/etc/config/xl2tpd + + $(INSTALL_DIR) $(1)/lib/netifd/proto + $(INSTALL_BIN) ./files/l2tp.sh $(1)/lib/netifd/proto/l2tp.sh +endef + +$(eval $(call BuildPackage,xl2tpd-ext)) diff --git a/xl2tpd-ext/files/l2tp-down b/xl2tpd-ext/files/l2tp-down new file mode 100644 index 00000000..d065644e --- /dev/null +++ b/xl2tpd-ext/files/l2tp-down @@ -0,0 +1,10 @@ +#!/bin/sh + +sed -i "/$1/d" /tmp/xl2tpd/clients + +[ -d /etc/ppp/ip-down.d ] && { + for SCRIPT in /etc/ppp/ip-down.d/* + do + [ -x "$SCRIPT" ] && "$SCRIPT" "$@" + done +} diff --git a/xl2tpd-ext/files/l2tp-up b/xl2tpd-ext/files/l2tp-up new file mode 100644 index 00000000..da2e3af9 --- /dev/null +++ b/xl2tpd-ext/files/l2tp-up @@ -0,0 +1,17 @@ +#!/bin/sh + +mkdir /tmp/xl2tpd +echo "ifname:$1;server:$4;client:$5" >> /tmp/xl2tpd/clients + +section=$(uci show xl2tpd | grep $5 | awk -F '.' '{print $2}') +route=$(uci get xl2tpd.$section.route) +[ -n "$route" ] && { + ip route add $route via $4 dev $1 +} + +[ -d /etc/ppp/ip-up.d ] && { + for SCRIPT in /etc/ppp/ip-up.d/* + do + [ -x "$SCRIPT" ] && "$SCRIPT" "$@" + done +} diff --git a/xl2tpd-ext/files/l2tp.sh b/xl2tpd-ext/files/l2tp.sh new file mode 100644 index 00000000..294c3dde --- /dev/null +++ b/xl2tpd-ext/files/l2tp.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +[ -x /usr/sbin/xl2tpd ] || exit 0 + +[ -n "$INCLUDE_ONLY" ] || { + . /lib/functions.sh + . ../netifd-proto.sh + init_proto "$@" +} + +proto_l2tp_init_config() { + proto_config_add_string "username" + proto_config_add_string "password" + proto_config_add_string "keepalive" + proto_config_add_string "pppd_options" + proto_config_add_boolean "ipv6" + proto_config_add_int "mtu" + proto_config_add_int "checkup_interval" + proto_config_add_string "server" + available=1 + no_device=1 + no_proto_task=1 + teardown_on_l3_link_down=1 +} + +proto_l2tp_setup() { + local interface="$1" + local optfile="/tmp/l2tp/options.${interface}" + local ip serv_addr server host + + json_get_var server server + host="${server%:*}" + for ip in $(resolveip -t 5 "$host"); do + ( proto_add_host_dependency "$interface" "$ip" ) + serv_addr=1 + done + [ -n "$serv_addr" ] || { + echo "Could not resolve server address" >&2 + sleep 5 + proto_setup_failed "$interface" + exit 1 + } + + # Start and wait for xl2tpd + if [ ! -p /var/run/xl2tpd/l2tp-control -o -z "$(pidof xl2tpd)" ]; then + /etc/init.d/xl2tpd restart + + local wait_timeout=0 + while [ ! -p /var/run/xl2tpd/l2tp-control ]; do + wait_timeout=$(($wait_timeout + 1)) + [ "$wait_timeout" -gt 5 ] && { + echo "Cannot find xl2tpd control file." >&2 + proto_setup_failed "$interface" + exit 1 + } + sleep 1 + done + fi + + local ipv6 keepalive username password pppd_options mtu + json_get_vars ipv6 keepalive username password pppd_options mtu + [ "$ipv6" = 1 ] || ipv6="" + + local interval="${keepalive##*[, ]}" + [ "$interval" != "$keepalive" ] || interval=5 + + keepalive="${keepalive:+lcp-echo-interval $interval lcp-echo-failure ${keepalive%%[, ]*}}" + username="${username:+user \"$username\" password \"$password\"}" + ipv6="${ipv6:++ipv6}" + mtu="${mtu:+mtu $mtu mru $mtu}" + + mkdir -p /tmp/l2tp + cat <"$optfile" +usepeerdns +nodefaultroute +ipparam "$interface" +ifname "l2tp-$interface" +ip-up-script /lib/netifd/ppp-up +ipv6-up-script /lib/netifd/ppp-up +ip-down-script /lib/netifd/ppp-down +ipv6-down-script /lib/netifd/ppp-down +# Don't wait for LCP term responses; exit immediately when killed. +lcp-max-terminate 0 +$keepalive +$username +$ipv6 +$mtu +$pppd_options +EOF + + xl2tpd-control add-lac l2tp-${interface} pppoptfile=${optfile} lns=${server} || { + echo "xl2tpd-control: Add l2tp-$interface failed" >&2 + proto_setup_failed "$interface" + exit 1 + } + xl2tpd-control connect-lac l2tp-${interface} || { + echo "xl2tpd-control: Connect l2tp-$interface failed" >&2 + proto_setup_failed "$interface" + exit 1 + } +} + +proto_l2tp_teardown() { + local interface="$1" + local optfile="/tmp/l2tp/options.${interface}" + + rm -f ${optfile} + if [ -p /var/run/xl2tpd/l2tp-control ]; then + xl2tpd-control remove-lac l2tp-${interface} || { + echo "xl2tpd-control: Remove l2tp-$interface failed" >&2 + } + fi + # Wait for interface to go down + while [ -d /sys/class/net/l2tp-${interface} ]; do + sleep 1 + done +} + +[ -n "$INCLUDE_ONLY" ] || { + add_protocol l2tp +} diff --git a/xl2tpd-ext/files/options.xl2tpd b/xl2tpd-ext/files/options.xl2tpd new file mode 100644 index 00000000..acd72619 --- /dev/null +++ b/xl2tpd-ext/files/options.xl2tpd @@ -0,0 +1,24 @@ +# +noauth +#debug +dump +logfd 2 +logfile /var/log/xl2tpd.log +noccp +novj +novjccomp +nopcomp +noaccomp +mtu 1400 +mru 1400 +require-mschap-v2 +lcp-echo-interval 20 +lcp-echo-failure 5 +connect-delay 5000 +nodefaultroute +noipdefault +proxyarp +ip-up-script /etc/xl2tpd/l2tp-up +#ipv6-up-script /etc/xl2tpd/l2tp-up +ip-down-script /etc/xl2tpd/l2tp-down +#ipv6-down-script /etc/xl2tpd/l2tp-down diff --git a/xl2tpd-ext/files/xl2tpd.conf b/xl2tpd-ext/files/xl2tpd.conf new file mode 100644 index 00000000..f826c85b --- /dev/null +++ b/xl2tpd-ext/files/xl2tpd.conf @@ -0,0 +1,23 @@ +[global] +port = 1701 +access control = no + +;[lns default] +;exclusive = yes +;ip range = 192.168.254.202-192.168.254.210 +;lac = 10.0.1.2 +;hidden bit = no +;local ip = 192.168.254.200 +;length bit = yes +;refuse authentication = yes +;name = VersaLink +;ppp debug = yes +;pppoptfile = /etc/ppp/options.xl2tpd + +;[lac left] +;lns = 10.0.1.2 +;refuse authentication = yes +;name = VersaLink +;ppp debug = yes +;pppoptfile = /etc/ppp/options.xl2tpd + diff --git a/xl2tpd-ext/files/xl2tpd.config b/xl2tpd-ext/files/xl2tpd.config new file mode 100644 index 00000000..05627542 --- /dev/null +++ b/xl2tpd-ext/files/xl2tpd.config @@ -0,0 +1,2 @@ +config service 'xl2tpd' + option 'enabled' '0' diff --git a/xl2tpd-ext/files/xl2tpd.init b/xl2tpd-ext/files/xl2tpd.init new file mode 100644 index 00000000..43bf3f9b --- /dev/null +++ b/xl2tpd-ext/files/xl2tpd.init @@ -0,0 +1,107 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2015 OpenWrt.org + +START=60 +USE_PROCD=1 + +BIN=xl2tpd +CONFIG=/var/etc/xl2tpd.conf +CHAP_SECRETS=/var/etc/chap-secrets +OPTIONS_XL2TPD=/var/etc/options.xl2tpd +RUN_D="/var/run/xl2tpd" +PID_F="/var/run/xl2tpd.pid" + +validate_login_section() { + uci_load_validate xl2tpd login "$1" "$2" \ + 'enabled:bool' \ + 'username:string' \ + 'password:string' \ + 'remoteip:string' +} + +validate_xl2tpd_section() { + uci_load_validate xl2tpd service "$1" "$2" \ + 'enabled:bool' \ + 'localip:string' \ + 'remoteip_start:string' \ + 'remoteip_end:string' +} + +setup_login() { + [ "$2" = 0 ] || { + echo "validation failed" + return 1 + } + + [ "$enabled" -eq 1 ] || return 0 + [ -n "$username" ] || return 0 + [ -n "$password" ] || return 0 + [ -n "$remoteip" ] || remoteip=* + + echo "$username l2tp-server $password $remoteip" >> $CHAP_SECRETS +} + +setup_config() { + [ "$2" = 0 ] || { + echo "validation failed" + return 1 + } + + mkdir -p /var/etc + rm -rf $CONFIG + cp /etc/xl2tpd/xl2tpd.conf $CONFIG + cp /etc/ppp/options.xl2tpd $OPTIONS_XL2TPD + + [ "$enabled" -eq 1 ] || return 0 + echo "[lns l2tp-server]" >> $CONFIG + [ -n "$localip" ] && echo "local ip = $localip" >> $CONFIG + [ -n "$remoteip_start" ] && [ -n "$remoteip_end" ] && echo "ip range = $remoteip_start-$remoteip_end" >> $CONFIG + echo "lac = 0.0.0.0-255.255.255.255" >> $CONFIG + echo "require chap = yes" >> $CONFIG + echo "require pap = yes" >> $CONFIG + echo "refuse authentication = yes" >> $CONFIG + echo "name = l2tp-server" >> $CONFIG + echo "pppoptfile = $OPTIONS_XL2TPD" >> $CONFIG + + return 0 +} + +start_service() { + config_load xl2tpd + validate_xl2tpd_section xl2tpd setup_config || return + sed -i '/l2tp-server/d' $CHAP_SECRETS + config_foreach validate_login_section login setup_login + + ln -sfn $CHAP_SECRETS /etc/ppp/chap-secrets + + rm -rf "$RUN_D" + mkdir -p "$RUN_D" + procd_open_instance + procd_set_param command $BIN -D -l -p "$PID_F" -c $CONFIG -s $CHAP_SECRETS + procd_set_param respawn + procd_close_instance +} + +service_triggers () { + procd_add_reload_trigger "xl2tpd" + + procd_open_validate + validate_xl2tpd_section + validate_login_section + procd_close_validate +} + +stop_service() { + if [[ -e "$PID_F" ]]; then + PID=$(cat "$PID_F") + CHILDS=$(pgrep -P "$PID") + kill "$PID" + kill "$CHILDS" + rm -rf "$RUN_D" + rm -rf "$PID_F" + fi +} + +reload_service() { + restart +} diff --git a/zabbix-config/Makefile b/zabbix-config/Makefile new file mode 100755 index 00000000..5f19b76d --- /dev/null +++ b/zabbix-config/Makefile @@ -0,0 +1,44 @@ + +include $(TOPDIR)/rules.mk + +PKG_NAME:=zabbix-config +PKG_VERSION:=1 +PKG_RELEASE:=1 +PKG_BUILD_DIR:=$(BUILD_DIR)/zabbix-config + +include $(INCLUDE_DIR)/package.mk + +define Package/zabbix-config + SECTION:=admin + CATEGORY:=Administration + SUBMENU:=Zabbix + TITLE:=Zabbix-config + TITLE:=Additional configuration and init for zabbix-agent + PKGARCH:=all +endef + +define Package/zabbix-config/description + This package contains a changed config and init file for zabbix_agentd +endef + +define Build/Prepare +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/zabbix-config/install + $(INSTALL_DIR) $(1)/etc + $(INSTALL_BIN) ./files/zabbix_agentd.conf $(1)/etc/zabbix_agentd.conf + $(INSTALL_DIR) $(1)/etc/zabbix_agentd.conf.d + $(INSTALL_BIN) ./files/device_template.conf $(1)/etc/zabbix_agentd.conf.d/ + $(INSTALL_DIR) $(1)/etc/config + $(CP) ./files/zabbix.config $(1)/etc/config/zabbix + $(INSTALL_DIR) $(1)/etc/init.d + $(INSTALL_BIN) ./files/zabbix_agentd.init $(1)/etc/init.d/zabbix_agentd +endef + +$(eval $(call BuildPackage,zabbix-config)) diff --git a/zabbix-config/files/device_template.conf b/zabbix-config/files/device_template.conf new file mode 100644 index 00000000..9fee1a95 --- /dev/null +++ b/zabbix-config/files/device_template.conf @@ -0,0 +1,18 @@ +###DEVICE### +UserParameter=device_hostname,getinfo hostname +UserParameter=device_serial,getinfo serialnum +UserParameter=device_fw,getinfo release +UserParameter=device_voltage,getinfo voltage +UserParameter=device_temp,getinfo temp +UserParameter=device_uptime,getinfo uptime +#MODEM +UserParameter=modem_imei,getinfo imei +UserParameter=modem_data,getinfo packtype +UserParameter=modem_operator,getinfo operator +UserParameter=modem_csq,getinfo signal +UserParameter=modem_sim_imsi,getinfo imsi +UserParameter=modem_sim_ccid,getinfo ccid +UserParameter=modem_sim_state,getinfo simstatus +#MWAN3 +UserParameter=wan_ip,getinfo wanip +UserParameter=current_wan,getinfo currentwan diff --git a/zabbix-config/files/zabbix.config b/zabbix-config/files/zabbix.config new file mode 100644 index 00000000..32836f0e --- /dev/null +++ b/zabbix-config/files/zabbix.config @@ -0,0 +1,3 @@ +config zabbix + option enabled '0' + diff --git a/zabbix-config/files/zabbix_agentd.conf b/zabbix-config/files/zabbix_agentd.conf new file mode 100644 index 00000000..62ff6f65 --- /dev/null +++ b/zabbix-config/files/zabbix_agentd.conf @@ -0,0 +1,5 @@ +LogType=system +StartAgents=1 +AllowRoot=1 +Include=/etc/zabbix_agentd.conf.d/ +Include=/tmp/zabbix_agentd.conf diff --git a/zabbix-config/files/zabbix_agentd.init b/zabbix-config/files/zabbix_agentd.init new file mode 100755 index 00000000..1e5a07c1 --- /dev/null +++ b/zabbix-config/files/zabbix_agentd.init @@ -0,0 +1,93 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2008-2011 OpenWrt.org + +START=60 + +USE_PROCD=1 +PROG=/usr/sbin/zabbix_agentd +CONFIG=/etc/zabbix_agentd.conf +TMP_CONFIG=/tmp/zabbix_agentd.conf + +start_service_daemon() { + config_get enabled "$1" enabled + config_get hostname "$1" hostname + config_get server "$1" server + config_get listen_ip "$1" listen_ip + config_get listen_port "$1" listen_port + config_get tls_accept "$1" tls_accept + config_get server_active "$1" server_active + config_get tls_connect "$1" tls_connect + config_get tls_psk_identity "$1" tls_psk_identity + config_get tls_psk_file "$1" tls_psk_file + config_get tls_ca_file "$1" tls_ca_file + config_get tls_cert_file "$1" tls_cert_file + config_get tls_key_file "$1" tls_key_file + + [ -f ${CONFIG} ] || return 1 + + [ "$enabled" = 0 ] && { + echo "service disabled" + return 0 + } + + [ -z "${server}" -o -z "${hostname}" ] && { + echo "hostname or server are not set" + return 0 + } + + #FIXME + [ -f ${TMP_CONFIG} ] && rm ${TMP_CONFIG} + touch ${TMP_CONFIG} + + server=$(echo ${server} | sed -r 's/[ ]+/,/g') + echo "Server=${server}" >> ${TMP_CONFIG} + echo "Hostname=${hostname}" >> ${TMP_CONFIG} + + [ -n "${listen_ip}" ] && echo "ListenIP=${listen_ip}" >> ${TMP_CONFIG} + [ -n "${listen_port}" ] && echo "ListenPort=${listen_port}" >> ${TMP_CONFIG} + [ -n "${tls_accept}" ] && { + tls_accept=$(echo ${tls_accept} | sed -r 's/[ ]+/,/g') + echo "TLSAccept=${tls_accept}" >> ${TMP_CONFIG} + } + + [ -n "${server_active}" ] && echo "ServerActive=${server_active}" >> ${TMP_CONFIG} + [ -n "${tls_connect}" ] && echo "TLSConnect=${tls_connect}" >> ${TMP_CONFIG} + [ -n "${tls_psk_identity}" ] && echo "TLSPSKIdentity=${tls_psk_identity}" >> ${TMP_CONFIG} + [ -n "${tls_psk_file}" ] && { + echo "TLSPSKFile=${tls_psk_file}" >> ${TMP_CONFIG} + chmod 644 ${tls_psk_file} + } + [ -n "${tls_ca_file}" ] && { + echo "TLSCAFile=${tls_ca_file}" >> ${TMP_CONFIG} + chmod 644 ${tls_ca_file} + } + [ -n "${tls_cert_file}" ] && { + echo "TLSCertFile=${tls_cert_file}" >> ${TMP_CONFIG} + chmod 644 ${tls_cert_file} + } + [ -n "${tls_key_file}" ] && { + echo "TLSKeyFile=${tls_key_file}" >> ${TMP_CONFIG} + chmod 644 ${tls_key_file} + } + + procd_open_instance + procd_set_param command ${PROG} -c ${CONFIG} -f + procd_set_param respawn + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_close_instance +} + +start_service(){ + config_load 'zabbix' + config_foreach start_service_daemon 'zabbix' +} + +service_triggers() { + procd_add_reload_trigger 'zabbix' +} + +reload_service() { + stop + start +}