Feat: add support for qfirehose 1.4.21

This commit is contained in:
sfwtw 2025-03-06 18:21:10 +08:00
parent 9e4386988d
commit 729bebe78f
28 changed files with 9583 additions and 3 deletions

View File

@ -44,6 +44,7 @@ In the configuration menu, you can select the following packages (all under Luci
| **QMI Driver Selection** | Choose between Generic QMI driver or Vendor QMI driver. |
| **Quectel Connect Manager Selection** | Choose one of:<br>- Tom customized Quectel CM: With options to block default route addition and resolv.conf modification<br>- QWRT quectel-CM-5G: Uses QWRT's quectel-CM-5G<br>- NORMAL quectel-cm: Uses the standard quectel-cm |
| **Add PCIe Modem SUPPORT** | Select PCIe driver, requires kmod_mhi in feeds. |
| **Add Qfirehose SUPPORT** | Add Qfirehose support for Qualcomm chip module firmware upgrade. |
| **luci-app-qmodem-hc** | Supports hc-g80 SIM card switching, exclusive to specific devices. |
| **luci-app-qmodem-mwan** | Supports multi-WAN settings. |
| **luci-app-qmodem-sms** | SMS sending feature. |

View File

@ -44,15 +44,15 @@ make menuconfig
| -------------------------------------------- | :------------------: |
| **luci-app-qmodem**| 有模组信息、拨号设置、高级设置三大功能块。由于主程序在这里,因此其他功能依赖该程序(原谅我将后端程序也放在了这里)。|
| **Add Lua Luci Homepage**| 添加 Lua Luci 首页。luci2Js Luci首页默认已添加若使用luci2时勾选了这个会有两个首页|
| **QMI驱动选择**| 可选择 Generic QMI driver通用QMI驱动或 Vendor QMI driver厂商QMI驱动|
| **Quectel Connect Manager选择**| 可选择以下三种之一:<br>- Tom customized Quectel CM使用本仓库定制的Quectel CM支持屏蔽添加默认路由、屏蔽修改resolv.conf等功能<br>- QWRT Quectel-CM-5G使用 QWRT 仓库的 quectel-CM-5G<br>- NORMAL Quectel-CM使用普通的 quectel-cm|
| **QMI Driver Selection**| 可选择 Generic QMI driver通用QMI驱动或 Vendor QMI driver厂商QMI驱动|
| **Quectel Connect Manager Selection**| 可选择以下三种之一:<br>- Tom customized Quectel CM使用本仓库定制的Quectel CM支持屏蔽添加默认路由、屏蔽修改resolv.conf等功能<br>- QWRT Quectel-CM-5G使用 QWRT 仓库的 quectel-CM-5G<br>- NORMAL Quectel-CM使用普通的 quectel-cm|
| **Add PCIe Modem SUPPORT**| 勾选 PCIe 驱动需要feeds里有kmod_mhi|
| **Add Qfirehose SUPPORT**| 添加 Qfirehose 支持,用于高通芯片模组固件升级|
| **luci-app-qmodem-hc**| 支持 hc-g80 SIM 卡切换,该插件为设备专属插件|
| **luci-app-qmodem-mwan**| 支持多 WAN 设置。|
| **luci-app-qmodem-sms**| 短信首发功能|
| **luci-app-qmodem-ttl**| TTL 重写功能|
# 项目介绍
## 为什么选择该项目

View File

@ -0,0 +1,52 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=qfirehose
PKG_VERSION:=1.4.21
PKG_RELEASE:=1
PKG_MAINTAINER:=Oskari Rauta <oskari.rauta@gmail.com>
PKG_LICENSE:=
PKG_LICENSE_FILES:=NOTICE
include $(INCLUDE_DIR)/package.mk
define Package/qfirehose
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Quectel Firehose Recovery application
URL:=https://github.com/nippynetworks/qfirehose
endef
define Package/qfirehose/description
Utility that is able to flash firmwares on Quectel's modems.
Usage: qfirehose -f FW_PATH
Warning.
- Use of software is completely on your own risk.
Flashing wrong firmware or failed flash can brick your modem permanently.
Avoid flashing, if device works without issues and updated firmware does not contain new necessary changes.
Do not flash, if you are not willing to take this risk or do not know what you are doing.
- After succesful flashing, you should use terminal to issue factory reset for modem settings with AT&F command.
- mPCIe users (mostly): If modem has completely disappeared after succesful flashing, reason might be that some firmware updates
set default mode to USB3 which is unsupported by some mPCIe slots, in this case, you should connect it to USB
port using mPCIe -> USB adapter, even most of cheap chinese modules can reveal device. After this you should issue
a command to use USB2, which may vary between models, but on most Quectel modems is: AT+QUSBCFG="SS",0
Changing value on end of AT command 0 to 1, selects USB3 instead. Refer to documents of your modem.
endef
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
MAKE_ARGS += linux
define Package/qfirehose/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/out/QFirehose $(1)/usr/bin/qfirehose
endef
$(eval $(call BuildPackage,qfirehose))

View File

@ -0,0 +1,167 @@
---
BasedOnStyle: Google
---
Language: Cpp
AccessModifierOffset: -4
# AlignAfterOpenBracket: Align
# AlignConsecutiveMacros: false
# AlignConsecutiveAssignments: false
# AlignConsecutiveDeclarations: false
# AlignEscapedNewlines: Left
# AlignOperands: true
# AlignTrailingComments: true
# AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: false
# AllowAllParametersOfDeclarationOnNextLine: true
# AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: true
# AllowShortFunctionsOnASingleLine: All
# AllowShortLambdasOnASingleLine: All
# AllowShortIfStatementsOnASingleLine: WithoutElse
# AllowShortLoopsOnASingleLine: true
# AlwaysBreakAfterDefinitionReturnType: None
# AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
# AlwaysBreakTemplateDeclarations: Yes
# BinPackArguments: true
# BinPackParameters: true
BraceWrapping:
# AfterCaseLabel: false
AfterClass: true
AfterControlStatement: Always
AfterEnum: true
AfterFunction: true
# AfterNamespace: false
# AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
# IndentBraces: false
# SplitEmptyFunction: true
# SplitEmptyRecord: true
# SplitEmptyNamespace: true
# BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
# BreakBeforeInheritanceComma: false
# BreakInheritanceList: BeforeColon
# BreakBeforeTernaryOperators: true
# BreakConstructorInitializersBeforeComma: false
# BreakConstructorInitializers: BeforeColon
# BreakAfterJavaFieldAnnotations: false
# BreakStringLiterals: true
ColumnLimit: 180
CommentPragmas: "^ NOLINT:"
# CompactNamespaces: false
# ConstructorInitializerAllOnOneLineOrOnePerLine: true
# ConstructorInitializerIndentWidth: 4
# ContinuationIndentWidth: 4
# Cpp11BracedListStyle: true
# DeriveLineEnding: true
# DerivePointerAlignment: true
# DisableFormat: false
# ExperimentalAutoDetectBinPacking: false
# FixNamespaceComments: true
# ForEachMacros:
# - foreach
# - Q_FOREACH
# - BOOST_FOREACH
# IncludeBlocks: Regroup
# IncludeCategories:
# - Regex: '^<ext/.*\.h>'
# Priority: 2
# SortPriority: 0
# - Regex: '^<.*\.h>'
# Priority: 1
# SortPriority: 0
# - Regex: "^<.*"
# Priority: 2
# SortPriority: 0
# - Regex: ".*"
# Priority: 3
# SortPriority: 0
# IncludeIsMainRegex: "([-_](test|unittest))?$"
# IncludeIsMainSourceRegex: ""
# IndentCaseLabels: true
# IndentGotoLabels: true
# IndentPPDirectives: None
IndentWidth: 4
# IndentWrappedFunctionNames: false
# JavaScriptQuotes: Leave
# JavaScriptWrapImports: true
# KeepEmptyLinesAtTheStartOfBlocks: false
# MacroBlockBegin: ""
# MacroBlockEnd: ""
# MaxEmptyLinesToKeep: 1
# NamespaceIndentation: None
# ObjCBinPackProtocolList: Never
# ObjCBlockIndentWidth: 2
# ObjCSpaceAfterProperty: false
# ObjCSpaceBeforeProtocolList: true
# PenaltyBreakAssignment: 2
# PenaltyBreakBeforeFirstCallParameter: 1
# PenaltyBreakComment: 300
# PenaltyBreakFirstLessLess: 120
# PenaltyBreakString: 1000
# PenaltyBreakTemplateDeclaration: 10
# PenaltyExcessCharacter: 1000000
# PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Right
# RawStringFormats:
# - Language: Cpp
# Delimiters:
# - cc
# - CC
# - cpp
# - Cpp
# - CPP
# - "c++"
# - "C++"
# CanonicalDelimiter: ""
# BasedOnStyle: google
# - Language: TextProto
# Delimiters:
# - pb
# - PB
# - proto
# - PROTO
# EnclosingFunctions:
# - EqualsProto
# - EquivToProto
# - PARSE_PARTIAL_TEXT_PROTO
# - PARSE_TEST_PROTO
# - PARSE_TEXT_PROTO
# - ParseTextOrDie
# - ParseTextProtoOrDie
# CanonicalDelimiter: ""
# BasedOnStyle: google
# ReflowComments: true
SortIncludes: false
SortUsingDeclarations: false
# SpaceAfterCStyleCast: false
# SpaceAfterLogicalNot: false
# SpaceAfterTemplateKeyword: true
# SpaceBeforeAssignmentOperators: true
# SpaceBeforeCpp11BracedList: false
# SpaceBeforeCtorInitializerColon: true
# SpaceBeforeInheritanceColon: true
# SpaceBeforeParens: ControlStatements
# SpaceBeforeRangeBasedForLoopColon: true
# SpaceInEmptyBlock: false
# SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
# SpacesInAngles: false
# SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
# SpacesInCStyleCastParentheses: false
# SpacesInParentheses: false
# SpacesInSquareBrackets: false
# SpaceBeforeSquareBrackets: false
Standard: Cpp11
# StatementMacros:
# - Q_UNUSED
# - QT_REQUIRE_VERSION
TabWidth: 4
# UseCRLF: false
# UseTab: Never

View File

@ -0,0 +1,8 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= firehose_protocol.c qfirehose.c sahara.c usb_linux.c stream_download_protocol.c md5.c usb2tcp.c
LOCAL_CFLAGS += -pie -fPIE -Wall -Wextra -Werror -O1
LOCAL_LDFLAGS += -pie -fPIE
LOCAL_MODULE_TAGS:= optional
LOCAL_MODULE:= QFirehose
include $(BUILD_EXECUTABLE)

View File

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 2.4)
project(QFirehose)
add_definitions(-Wall -Wextra -Werror -O1)
set( QFirehose_SRCS
firehose_protocol.c qfirehose.c sahara.c usb_linux.c stream_download_protocol.c md5.c usb2tcp.c
)
add_executable(QFirehose ${QFirehose_SRCS})
target_link_libraries(QFirehose PUBLIC pthread)
install (TARGETS QFirehose DESTINATION bin)

View File

@ -0,0 +1,22 @@
NDK_BUILD:=/home/aaron/share-aaron-1/android-ndk-r10e/ndk-build
SRC=firehose_protocol.c qfirehose.c sahara.c usb_linux.c stream_download_protocol.c md5.c usb2tcp.c
CFLAGS += -Wall -Wextra -Werror -g #-s
LDFLAGS += -lpthread -ldl
BINPATH := ./out
ifeq ($(CC),cc)
CC=${CROSS_COMPILE}gcc
endif
linux: clean
$(shell if [ -e ${BINPATH}]; then echo "file existed";else mkdir ${BINPATH}; fi;)
${CC} ${CFLAGS} ${SRC} -o ${BINPATH}/QFirehose ${LDFLAGS}
android: clean
rm -rf android
$(NDK_BUILD) V=0 APP_BUILD_SCRIPT=Android.mk NDK_PROJECT_PATH=`pwd` NDK_DEBUG=0 APP_ABI='armeabi-v7a,arm64-v8a' APP_PLATFORM=android-22 #16~4.1 22~5.1 25~7.1 27-32~8-12
rm -rf obj
mv libs android
clean:
rm -rf ${BINPATH}/QFirehose obj libs usb2tcp *~

View File

@ -0,0 +1,6 @@
Quectel hereby grants customers of Quectel a license to use, modify,
distribute and publish the Software in binary form provided that
customers shall have no right to reverse engineer, reverse assemble,
decompile or reduce to source code form any portion of the Software.
Under no circumstances may customers modify, demonstrate, use, deliver
or disclose any portion of the Software in source code form.

View File

@ -0,0 +1,108 @@
# QFIREHOSE 升级进度通知机制说明
> QFirehose 目前支持两种进度通知方式。基于文件的通知方式基于消息队列的通知机制。两种方式均可使用。Android设备由于系统限制system V IPC 机制支持不完善,不能支持消息队列的方式获取进度。
>
> 其中基于文件的形式很容易替换成,有名管道的形式,只需把创建并打开改成创建并打开管道的形式(参考`man mkfifio`)。「注:管道需要先以读方式打开,再以写方式打开,否则会有错误」
## 一、进度读写说明
> QFirehose 进度都是以<u>**整数**</u>形式写到文件或者消息队列里。
1. 在升级开始阶段写入进度**0**预示这升级开始。
2. 之后每次进度有变化都会重新更新进度信息。
3. 升级完成最后结果是**100**。
4. 升级发生异常会写入进度 **-1**. 「注:特殊情况,如程序异常崩溃进度信息可能来不及写入而是空的,需要第三方程序考虑文件内容为空的情况」
## 二、文件形式的通知机制
### A. 文件读写说明
文件方式的交互文件路径为: Android **“/data/update.conf”**, 其他 **“/tmp/update.conf”**。(修改QFirehose 源码可以修改这个文件)。另外需要保证/data 或者/tmp 这个目录存在且QFirehose有读写、创建文件的权限。
由于文件是持续存在磁盘上的。为了保证命令行方式的cat 读与标准API 的read 两种方式的可读性。<u>**进度写方式为覆盖写,意思就是新的进度会覆盖掉之前的内容。**</u>表现在实现上就是,每次写之前移动文件指针到文件头,然后写入进度。读进度时候需要注意这一点!!!
另外注意的是QFirehose 不负责文件的删除,如果需要删除需要由第三方程序在升级结束/出错删除进度文件!
### B.使用说明
QFirehose 默认不使能通知功能。如需使能文件方式通知逻辑需要在编译时指定宏 **USE_IPC_FILE** , 建议在Makefile里用 **-DUSE_IPC_FILE**来使能. 如下代码所示
```makefile
NDK_BUILD:=/workspace/android-ndk/android-ndk-r10e/ndk-build
ifeq ($(CC),cc)
CC=${CROSS_COMPILE}gcc
endif
cflags += -Wno-format-overflow
linux: clean
${CC} -g -Wall -DUSE_IPC_FILE -s ${cflags} firehose_protocol.c qfirehose.c sahara_protocol.c usb_linux.c stream_download_protocol.c md5.c usb2tcp.c -o QFirehose -lpthread -ldl
clean:
rm -rf QFirehose obj libs android usb2tcp *~
```
## 三、消息队列的通知机制
### A. 原理说明
System V 方式消息队列。QFirehose 负责创建消息队列,写入进度。**不负责删除消息,不负责删除消息队列。**
如下图QFirehose 定义的消息结构体消息类型与message key 获取机制。第三方应用需要与QFirehose 保持一致。如需修改可以修改QFirehose 源码。
System V message queue
```c
#define MSGBUFFSZ 16
struct message
{
long mtype;
char mtext[MSGBUFFSZ];
};
#define MSG_FILE "/etc/passwd"
#define MSG_TYPE_IPC 1
```
并同时修改编译脚本/源码,定义宏 **USE_IPC_MSG**, 如下所示
```makefile
NDK_BUILD:=/workspace/android-ndk/android-ndk-r10e/ndk-build
ifeq ($(CC),cc)
CC=${CROSS_COMPILE}gcc
endif
cflags += -Wno-format-overflow
linux: clean
${CC} -g -Wall -DUSE_IPC_MSG -s ${cflags} firehose_protocol.c qfirehose.c sahara_protocol.c usb_linux.c stream_download_protocol.c md5.c usb2tcp.c -o QFirehose -lpthread -ldl
clean:
rm -rf QFirehose obj libs android usb2tcp *~
```
QFirehose 实现了四个操作函数:消息队列的创建,删除,写,读。但是只用到了创建与读函数。另外两个仅供参考与测试用。
### B.使用说明
QFirehose 负责创建消息队列,写入进度。不会删除消息以及消息队列。建议第三方应用在升级程序退出之后主动删除消息队列。
QFirehose 支持对消息队列的测试,这需要启用宏 **IPC_TEST** 。开启这个宏之后QFirehose 会在写入消息后再次读取消息,并打印到`STDOUT`,检查打印可知是否正确。
```c
/**
* this function will not delete the msg queue
*/
int update_progress_msg(int percent)
{
char buff[MSGBUFFSZ];
int msgid = msg_get();
if (msgid < 0)
return -1;
snprintf(buff, sizeof(buff), "%d", percent);
#ifndef IPC_TEST
return msg_send(msgid, MSG_TYPE_IPC, buff);
#else
msg_send(msgid, MSG_TYPE_IPC, buff);
struct message info;
info.mtype = MSG_TYPE_IPC;
msg_recv(msgid, &info);
printf("msg queue read: %s\n", info.mtext);
#endif
}
```

View File

@ -0,0 +1,198 @@
Release Notes
[QFirehose_Linux_Android_V1.4.21]
Date: 08/14/2024
enhancement:
1. Support EG120KEABA upgrade in RNDIS mode
fix:
[QFirehose_Linux_Android_V1.4.20]
Date: 07/18/2024
enhancement:
1. Support AG600K to upgrade using adb command let module into edl
2. Support sec-boot upgrade file to burn
fix:
Release Notes
[QFirehose_Linux_Android_V1.4.19]
Date: 04/30/2024
enhancement:
1. The input parameter can be a precise file to specify the reading of the upgrade file.
2. RG650V using rndis can use this tool to upgrade.(./QFirehose -f ${upgrade_file_path} -d emmc)
fix:
[QFirehose_Linux_Android_V1.4.18]
Date: 12/29/2023
enhancement:
1. New support for upgrading the laptop module EM120K-GL
2. New support for SA885GAPNA(ufs) upgrade
3. Added support for AG215SGLBA(with a single image greater than 40M in the firmware package) upgrade
4. New support for RM520NGL(custom PID is 0x0804) upgrade
fix:
[QFirehose_Linux_Android_V1.4.17]
Date: 09/13/2023
enhancement:
1. Added support for upgrading using zip and 7z package
2. Optimize pcie code
3. Optimize sahara code
fix:
[QFirehose_Linux_Android_V1.4.16]
Date: 08/08/2023
enhancement:
1. Update copyright
2. Hide -e full wipe, but retain this feature
3. Fix errors in klocwork scanning
4. Code optimization for erase partitioning operations for nand storage modules
fix:
[QFirehose_Linux_Android_V1.4.15]
Date: 06/29/2023
enhancement:
1. Added support for upgrading laptop EM05G-SE10
2. Modify the copyright time and add copyright to some c or h files
3. Optimize sahara protocol code
fix:
[QFirehose_Linux_Android_V1.4.14]
Date: 04/29/2023
enhancement:
1. Added support for upgrading laptop EM05-G and EM061KGL
2. Added support for AG590ECNAB upgrade
3. Added support for upgrading the RM520NGL Lenovo 5G module (with a specified PID of 0x0803)
4. Added support for upgrading AG215S-GLR signed firmware version packs
fix:
[QFirehose_Linux_Android_V1.4.13]
Date: 02/20/2023
enhancement:
1. New support for upgrading multiple PCIE modules in a specified way, with a maximum of 10 PCIE modules connected at the same time
2. Optimization module connection USB3.0 upgrade
fix:
[QFirehose_Linux_Android_V1.4.12]
Date: 12/15/2022
enhancement:
1. Added support for Qualcomm subcontracting firmware upgrade (also compatible with non subcontracting firmware)
2. Added EC20<32><30>3C93 FFFF<46><46>upgrade
3. Add BG95M3 anti misburning function
4. Add other device type full wipe upgrade functions except nand
fix:
[QFirehose_Linux_Android_V1.4.11]
Date: 08/29/2022
enhancement:
1. Better support emmc and ufs smart module
2. remove function upgrade one file by '-f filename', nobody use it
and make source code complex and difficult to understand.
if customer need this function, can by modify firehose/rawprogram_nand_p4K_b256K_factory.xml
3. if there is no md5.txt, just ignore, donot treat as error
4. New support for upgrading Qualcomm AG215SGLR module and AG215SGLBA module
fix:
[QFirehose_Linux_Android_V1.4.10]
Date: 07/15/2022
enhancement:
1. New support for laptop EM05 series and EG060K-EA module upgrade
fix:
[QFirehose_Linux_Android_V1.4.9]
Date: 01/17/2022
enhancement:
1. Solve the problem that DM upgrade is stuck because DM keeps spitting logs
fix:
[QFirehose_Linux_Android_V1.4.8]
Date: 11/12/2021
enhancement:
1. EM05CE Interface0 is a non-DM port with input and output endpoints. The actual DM port is Interface3
2. EM05-G Upgrade Process Power off and power on. The next upgrade takes a long time to switch to download mode. Increase the waiting time to 10 seconds
3. Optimized receiving and sending buf, no longer sharing one buf
fix:
[QFirehose_Linux_Android_V1.4.7]
Date: 9/28/2021
enhancement:
1. Support EM05-G, DM is at usb interface 3
2. Added support for smart platform SC600Y-EM and SC60-CE upgrade
3. Support sdx20 quallcomm default 056c/901f
fix:
[Quectel_LTE&5G_QFirehose_Linux&Android_V1.4.6]
Date: 6/11/2021
enhancement:
fix:
1. <20><><EFBFBD>Ӷ<EFBFBD>EC20<32><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
[Quectel_LTE&5G_QFirehose_Linux&Android_V1.4.5]
Date: 3/4/2021
enhancement:
fix:
1. fix upgrdae fail of AG550/EM120
[Quectel_LTE&5G_QFirehose_Linux&Android_V1.4.4]
Date: 1/27/202
enhancement:
fix:
1. increase timeout of erase cmd to 15 seconds (from 6 seconds)
[Quectel_LTE&5G_QFirehose_Linux&Android_V1.4.3]
Date: 12/2/2020
enhancement:
1. '-u usbmon.log': The time stamp in usbmon.log is same QFirehose self
2. USB ZLP: if kernel verison <= 4.2 and usb controoler type is XHCI.
there is a USB ZLP bug which cause FW upgrade fail at 0%,
print Warnning for this bug and tell customer how to fix.
fix:
1. AG35: FW upgrade fail (A very low probability) in one customer's factory
[Quectel_LTE&5G_QFirehose_Linux&Android_V1.4]
Date: 8/26/2020
enhancement:
1. release to <Technical Writer>
fix:
[Quectel_LTE&5G_QFirehose_Linux&Android_V1.3.3]
Date: 7/27/2020
enhancement:
fix:
1. AG525 has more than 32 partitions, support this
[Quectel_LTE&5G_QFirehose_Linux&Android_V1.3.2]
Date: 7/27/2020
enhancement:
fix:
1. filter out ASR/HISI modems, only support MDM/SDX modems
2. FW upgrade fail when USB3.0 modems switch EDL mode (05c6:9008),
will become usb2.0 device, and the /sys/bus/usb/devices/x-x will change
[Quectel_LTE&5G_QFirehose_Linux&Android_V1.3]
Date: 4/14/2020
enhancement:
1. X55 support upgrade from RAM DUMP state
fix:
[LTE&5G_QFirehose_Linux&Android_V1.2.4]
Date: 3/26/2020
enhancement:
1. make sure 'first erase SBL, last program SBL', even The sequence in update/firehose/rawprogram*.xml is wrong
fix:
[LTE&5G_QFirehose_Linux&Android_V1.2.3]
Date: 2/24/2019
enhancement:
1. support 'vendor' attribute in rawprogram*.xml
2. support '-u usbmon_logfile', can capture usbmon log when upgrade module.
fix:
[LTE&5G_QFirehose_Linux&Android_V1.2.2]
Date: 12/11/2019
enhancement:
1. auto detect and detach kernel driver when modem in EDL mode (05c6:9008).
fix:
1. Do not exit if get version command fails
[LTE&5G_QFirehose_Linux&Android_V1.2]
Date: 2019/07/31
enhancement:
1. First Release Version of QFirehose Tool.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,113 @@
/*
Copyright 2023 Quectel Wireless Solutions Co.,Ltd
Quectel hereby grants customers of Quectel a license to use, modify,
distribute and publish the Software in binary form provided that
customers shall have no right to reverse engineer, reverse assemble,
decompile or reduce to source code form any portion of the Software.
Under no circumstances may customers modify, demonstrate, use, deliver
or disclose any portion of the Software in source code form.
*/
#ifndef _HOSTDL_PACKET_H_
#define _HOSTDL_PACKET_H_
#define UNFRAMED_MAX_DATA_LENGTH 1024
#define FRAMED_MAX_DATA_LENGTH 1024
#define NUMBER_OF_PACKETS 2
#define HOST_REPLY_BUFFER_SIZE 1024
#define PACKET_OVERHEAD_SIZE 7
#define CMD_SIZE 1
#define MAGIC_SIZE 32
#define VERSION_SIZE 1
#define COMPAT_VERSION_SIZE 1
#define BLOCK_SIZE_SIZE 4
#define FLASH_BASE_SIZE 4
#define FLASH_ID_LEN_SIZE 1
#define WINDOW_SIZE_SIZE 2
#define NUM_SECTORS_SIZE 2
#define FEATURE_BITS_SIZE 4
#define FLASH_ID_STRING_SIZE 32
#define REPLY_FIXED_SIZE \
(PACKET_OVERHEAD_SIZE + CMD_SIZE + MAGIC_SIZE + VERSION_SIZE + COMPAT_VERSION_SIZE + \
BLOCK_SIZE_SIZE + FLASH_BASE_SIZE + FLASH_ID_LEN_SIZE + WINDOW_SIZE_SIZE + NUM_SECTORS_SIZE + \
FEATURE_BITS_SIZE + FLASH_ID_STRING_SIZE)
#define REPLY_BUFFER_SIZE HOST_REPLY_BUFFER_SIZE
#define MAX_SECTORS ((REPLY_BUFFER_SIZE - REPLY_FIXED_SIZE) / 4)
#define DEVICE_UNKNOWN 0xFF
#define MAX_PACKET_SIZE (UNFRAMED_MAX_DATA_LENGTH + 1 + 4 + 2 + 9)
#define STREAM_DLOAD_MAX_VER 0x04
#define STREAM_DLOAD_MIN_VER 0x02
#define UNFRAMED_DLOAD_MIN_VER 0x04
#define UART_DLOAD_MAX_VER 0x03
#if 0
#if defined(USE_UART_ONLY) && (STREAM_DLOAD_MAX_VER > UART_DLOAD_MAX_VER)
#warning UART does not support protocol versions beyond UART_DLOAD_MAX_VER. \
Reverting to an earlier protocol version.
#undef STREAM_DLOAD_MAX_VER
#define STREAM_DLOAD_MAX_VER UART_DLOAD_MAX_VER
#endif
#endif
#define FEATURE_UNCOMPRESSED_DLOAD 0x00000001
#define FEATURE_NAND_PRIMARY_IMAGE 0x00000002
#define FEATURE_NAND_BOOTLOADER_IMAGE 0x00000004
#define FEATURE_NAND_MULTI_IMAGE 0x00000008
#define SUPPORTED_FEATURES (FEATURE_UNCOMPRESSED_DLOAD | FEATURE_NAND_MULTI_IMAGE)
#define READ_LEN 7
#define HELLO_REQ 0x01
#define HELLO_RSP 0x02
#define READ_RSP 0x04
#define WRITE_RSP 0x06
#define STREAM_WRITE_RSP 0x08
#define NOP_RSP 0x0A
#define RESET_RSP 0x0C
#define ERROR_RSP 0x0D
#define CMD_LOG 0x0E
#define UNLOCK_RSP 0x10
#define PWRDOWN_RSP 0x12
#define OPEN_RSP 0x14
#define CLOSE_RSP 0x16
#define SECURITY_MODE_RSP 0x18
#define PARTITION_TABLE_RSP 0x1A
#define OPEN_MULTI_IMAGE_RSP 0x1C
#define ERASE_RSP 0x1E
#define UNFRAMED_STREAM_WRITE_CMD 0x30
#define UNFRAMED_STREAM_WRITE_RSP 0x31
#define DUMMY_RSP 0x32
#define FIRST_COMMAND 0x01
#define LAST_COMMAND 0x31
#if (DUMMY_RSP != (LAST_COMMAND + 1))
#error LAST_COMMAND and DUMMY_RSP mismatch. Bailing out!
#endif
#define SIZE_MSG_LEN 64
#define HELLO_CMD_OFFSET 0
#define HELLO_MAGIC_NUM_OFFSET 1
#define HELLO_MAX_VER_OFFSET 33
#define HELLO_MIN_VER_OFFSET 34
#define HELLO_MAX_DATA_SZ_1_OFFSET 35
#define HELLO_MAX_DATA_SZ_2_OFFSET 36
#define HELLO_MAX_DATA_SZ_3_OFFSET 37
#define HELLO_MAX_DATA_SZ_4_OFFSET 38
#endif

View File

@ -0,0 +1,581 @@
root@OpenWrt:~# ./QFirehose -f /mnt/RM500QGLAAR01A01M4G_BETA_20200428F
[000.000]: QFirehose Version: Quectel_LTE&5G_QFirehose_Linux&Android_V1.3.2
[000.000]: Builded: May 18 2020 11:32:04
[000.000]: Find md5 check file </mnt/RM500QGLAAR01A01M4G_BETA_20200428F_factory/md5.txt>
[000.002]: Totals checking 0 files md5 value, 0 file fail!
[000.019]: [1] /sys/bus/usb/devices/2-1.4 2c7c/800/414
[000.026]: P: /dev/bus/usb/002/006 idVendor=2c7c idProduct=0800
[000.026]: C: /dev/bus/usb/002/006 bNumInterfaces: 5
[000.026]: I: If#= 0 Alt= 0 #EPs= 2 Cls=ff Sub=ff Prot=30
[000.026]: E: Ad=81 Atr=02 MxPS= 1024 Ivl=0ms
[000.026]: E: Ad=01 Atr=02 MxPS= 1024 Ivl=0ms
[000.026]: I: If#= 1 Alt= 0 #EPs= 3 Cls=ff Sub=00 Prot=00
[000.027]: I: If#= 2 Alt= 0 #EPs= 3 Cls=ff Sub=00 Prot=00
[000.027]: I: If#= 3 Alt= 0 #EPs= 3 Cls=ff Sub=00 Prot=00
[000.027]: I: If#= 4 Alt= 0 #EPs= 3 Cls=ff Sub=ff Prot=ff
[000.027]: qusb_noblock_open port_name = /dev/ttyUSB0
[000.031]: old software version: RM500QGLAAR01A01M4G_BETA_20200428F
[001.032]: poll_wait events=POLLIN msec=1000 timeout
[001.032]: qusb_noblock_read cur=0, min_size=1
[001.032]: switch to 'Emergency download mode'
[001.034]: successful, wait module reboot
[002.035]: fail to fopen /sys/bus/usb/devices/2-1.4/uevent, errno: 2 (No such file or directory)
[003.041]: fail to fopen /sys/bus/usb/devices/2-1.4/uevent, errno: 2 (No such file or directory)
[004.045]: [1] /sys/bus/usb/devices/1-1.4 5c6/9008/0
[004.049]: P: /dev/bus/usb/001/012 idVendor=05c6 idProduct=9008
[004.049]: C: /dev/bus/usb/001/012 bNumInterfaces: 1
[004.049]: I: If#= 0 Alt= 0 #EPs= 2 Cls=ff Sub=ff Prot=11
[004.049]: E: Ad=81 Atr=02 MxPS= 512 Ivl=0ms
[004.049]: E: Ad=01 Atr=02 MxPS= 512 Ivl=0ms
[004.050]: dir=/mnt/RM500QGLAAR01A01M4G_BETA_20200428F_factory/update/firehose
[004.050]: dir=/mnt/RM500QGLAAR01A01M4G_BETA_20200428F_factory/update/firehose
[004.051]: d_name=prog_firehose_sdx55.mbn
[004.051]: prog_nand_firehose_filename = prog_firehose_sdx55.mbn
[004.051]: STATE <-- SAHARA_WAIT_HELLO
[004.052]: RECEIVED <-- SAHARA_HELLO_ID
[004.052]: RECEIVED <-- SAHARA_MODE_IMAGE_TX_PENDING
[004.052]: SENDING --> SAHARA_HELLO_RESPONSE
[004.052]: STATE <-- SAHARA_WAIT_COMMAND
[004.053]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.053]: 0x0000000d 0x00000000 0x00000034
[004.056]: STATE <-- SAHARA_WAIT_COMMAND
[004.056]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.056]: 0x0000000d 0x00000034 0x00000080
[004.056]: STATE <-- SAHARA_WAIT_COMMAND
[004.057]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.057]: 0x0000000d 0x00001000 0x00001000
[004.058]: STATE <-- SAHARA_WAIT_COMMAND
[004.087]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.087]: 0x0000000d 0x00002000 0x000009d0
[004.087]: STATE <-- SAHARA_WAIT_COMMAND
[004.088]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.088]: 0x0000000d 0x00003000 0x00001000
[004.093]: STATE <-- SAHARA_WAIT_COMMAND
[004.094]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.094]: 0x0000000d 0x00004000 0x00001000
[004.094]: STATE <-- SAHARA_WAIT_COMMAND
[004.095]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.095]: 0x0000000d 0x00005000 0x00001000
[004.095]: STATE <-- SAHARA_WAIT_COMMAND
[004.096]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.096]: 0x0000000d 0x00006000 0x00001000
[004.096]: STATE <-- SAHARA_WAIT_COMMAND
[004.097]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.097]: 0x0000000d 0x00007000 0x00001000
[004.098]: STATE <-- SAHARA_WAIT_COMMAND
[004.098]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.098]: 0x0000000d 0x00008000 0x00001000
[004.099]: STATE <-- SAHARA_WAIT_COMMAND
[004.099]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.099]: 0x0000000d 0x00009000 0x00001000
[004.100]: STATE <-- SAHARA_WAIT_COMMAND
[004.100]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.100]: 0x0000000d 0x0000a000 0x00001000
[004.101]: STATE <-- SAHARA_WAIT_COMMAND
[004.101]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.101]: 0x0000000d 0x0000b000 0x00001000
[004.103]: STATE <-- SAHARA_WAIT_COMMAND
[004.103]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.103]: 0x0000000d 0x0000c000 0x00001000
[004.104]: STATE <-- SAHARA_WAIT_COMMAND
[004.104]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.104]: 0x0000000d 0x0000d000 0x00001000
[004.105]: STATE <-- SAHARA_WAIT_COMMAND
[004.105]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.105]: 0x0000000d 0x0000e000 0x00001000
[004.106]: STATE <-- SAHARA_WAIT_COMMAND
[004.106]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.106]: 0x0000000d 0x0000f000 0x00001000
[004.107]: STATE <-- SAHARA_WAIT_COMMAND
[004.107]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.108]: 0x0000000d 0x00010000 0x00001000
[004.108]: STATE <-- SAHARA_WAIT_COMMAND
[004.108]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.109]: 0x0000000d 0x00011000 0x00001000
[004.109]: STATE <-- SAHARA_WAIT_COMMAND
[004.110]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.110]: 0x0000000d 0x00012000 0x00001000
[004.110]: STATE <-- SAHARA_WAIT_COMMAND
[004.111]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.111]: 0x0000000d 0x00013000 0x00001000
[004.111]: STATE <-- SAHARA_WAIT_COMMAND
[004.112]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.112]: 0x0000000d 0x00014000 0x00001000
[004.113]: STATE <-- SAHARA_WAIT_COMMAND
[004.113]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.113]: 0x0000000d 0x00015000 0x00001000
[004.114]: STATE <-- SAHARA_WAIT_COMMAND
[004.114]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.114]: 0x0000000d 0x00016000 0x00001000
[004.115]: STATE <-- SAHARA_WAIT_COMMAND
[004.115]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.115]: 0x0000000d 0x00017000 0x00001000
[004.116]: STATE <-- SAHARA_WAIT_COMMAND
[004.116]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.116]: 0x0000000d 0x00018000 0x00001000
[004.117]: STATE <-- SAHARA_WAIT_COMMAND
[004.117]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.117]: 0x0000000d 0x00019000 0x00001000
[004.118]: STATE <-- SAHARA_WAIT_COMMAND
[004.118]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.118]: 0x0000000d 0x0001a000 0x00001000
[004.119]: STATE <-- SAHARA_WAIT_COMMAND
[004.119]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.119]: 0x0000000d 0x0001b000 0x00001000
[004.120]: STATE <-- SAHARA_WAIT_COMMAND
[004.120]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.120]: 0x0000000d 0x0001c000 0x00001000
[004.121]: STATE <-- SAHARA_WAIT_COMMAND
[004.121]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.122]: 0x0000000d 0x0001d000 0x00001000
[004.122]: STATE <-- SAHARA_WAIT_COMMAND
[004.123]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.123]: 0x0000000d 0x0001e000 0x00001000
[004.123]: STATE <-- SAHARA_WAIT_COMMAND
[004.124]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.124]: 0x0000000d 0x0001f000 0x00001000
[004.124]: STATE <-- SAHARA_WAIT_COMMAND
[004.125]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.125]: 0x0000000d 0x00020000 0x00001000
[004.125]: STATE <-- SAHARA_WAIT_COMMAND
[004.126]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.126]: 0x0000000d 0x00021000 0x00001000
[004.126]: STATE <-- SAHARA_WAIT_COMMAND
[004.127]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.127]: 0x0000000d 0x00022000 0x00001000
[004.127]: STATE <-- SAHARA_WAIT_COMMAND
[004.128]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.128]: 0x0000000d 0x00023000 0x00001000
[004.128]: STATE <-- SAHARA_WAIT_COMMAND
[004.129]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.129]: 0x0000000d 0x00024000 0x00001000
[004.129]: STATE <-- SAHARA_WAIT_COMMAND
[004.130]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.130]: 0x0000000d 0x00025000 0x00001000
[004.130]: STATE <-- SAHARA_WAIT_COMMAND
[004.131]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.131]: 0x0000000d 0x00026000 0x00001000
[004.131]: STATE <-- SAHARA_WAIT_COMMAND
[004.132]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.132]: 0x0000000d 0x00027000 0x00001000
[004.132]: STATE <-- SAHARA_WAIT_COMMAND
[004.133]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.133]: 0x0000000d 0x00028000 0x00001000
[004.133]: STATE <-- SAHARA_WAIT_COMMAND
[004.134]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.134]: 0x0000000d 0x00029000 0x00001000
[004.134]: STATE <-- SAHARA_WAIT_COMMAND
[004.135]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.135]: 0x0000000d 0x0002a000 0x00001000
[004.135]: STATE <-- SAHARA_WAIT_COMMAND
[004.136]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.136]: 0x0000000d 0x0002b000 0x00000578
[004.136]: STATE <-- SAHARA_WAIT_COMMAND
[004.136]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.137]: 0x0000000d 0x0002b580 0x00001000
[004.137]: STATE <-- SAHARA_WAIT_COMMAND
[004.137]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.138]: 0x0000000d 0x0002c580 0x00001000
[004.138]: STATE <-- SAHARA_WAIT_COMMAND
[004.138]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.139]: 0x0000000d 0x0002d580 0x00001000
[004.139]: STATE <-- SAHARA_WAIT_COMMAND
[004.139]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.140]: 0x0000000d 0x0002e580 0x00001000
[004.140]: STATE <-- SAHARA_WAIT_COMMAND
[004.140]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.141]: 0x0000000d 0x0002f580 0x00001000
[004.141]: STATE <-- SAHARA_WAIT_COMMAND
[004.141]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.142]: 0x0000000d 0x00030580 0x00001000
[004.142]: STATE <-- SAHARA_WAIT_COMMAND
[004.143]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.143]: 0x0000000d 0x00031580 0x00001000
[004.143]: STATE <-- SAHARA_WAIT_COMMAND
[004.144]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.144]: 0x0000000d 0x00032580 0x00001000
[004.144]: STATE <-- SAHARA_WAIT_COMMAND
[004.145]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.145]: 0x0000000d 0x00033580 0x00001000
[004.145]: STATE <-- SAHARA_WAIT_COMMAND
[004.146]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.146]: 0x0000000d 0x00034580 0x00001000
[004.146]: STATE <-- SAHARA_WAIT_COMMAND
[004.147]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.147]: 0x0000000d 0x00035580 0x00001000
[004.147]: STATE <-- SAHARA_WAIT_COMMAND
[004.148]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.148]: 0x0000000d 0x00036580 0x00001000
[004.148]: STATE <-- SAHARA_WAIT_COMMAND
[004.149]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.149]: 0x0000000d 0x00037580 0x00001000
[004.149]: STATE <-- SAHARA_WAIT_COMMAND
[004.150]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.150]: 0x0000000d 0x00038580 0x00001000
[004.150]: STATE <-- SAHARA_WAIT_COMMAND
[004.151]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.151]: 0x0000000d 0x00039580 0x00001000
[004.151]: STATE <-- SAHARA_WAIT_COMMAND
[004.152]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.152]: 0x0000000d 0x0003a580 0x00001000
[004.152]: STATE <-- SAHARA_WAIT_COMMAND
[004.153]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.153]: 0x0000000d 0x0003b580 0x00001000
[004.153]: STATE <-- SAHARA_WAIT_COMMAND
[004.154]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.154]: 0x0000000d 0x0003c580 0x00001000
[004.154]: STATE <-- SAHARA_WAIT_COMMAND
[004.155]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.155]: 0x0000000d 0x0003d580 0x00001000
[004.155]: STATE <-- SAHARA_WAIT_COMMAND
[004.156]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.156]: 0x0000000d 0x0003e580 0x00001000
[004.156]: STATE <-- SAHARA_WAIT_COMMAND
[004.157]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.157]: 0x0000000d 0x0003f580 0x00001000
[004.157]: STATE <-- SAHARA_WAIT_COMMAND
[004.158]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.158]: 0x0000000d 0x00040580 0x00001000
[004.158]: STATE <-- SAHARA_WAIT_COMMAND
[004.159]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.159]: 0x0000000d 0x00041580 0x00001000
[004.159]: STATE <-- SAHARA_WAIT_COMMAND
[004.160]: RECEIVED <-- SAHARA_READ_DATA_ID
[004.160]: 0x0000000d 0x00042580 0x00000800
[004.160]: STATE <-- SAHARA_WAIT_COMMAND
[004.163]: RECEIVED <-- SAHARA_END_IMAGE_TX_ID
[004.163]: image_id = 13, status = 0
[004.164]: SENDING --> SAHARA_DONE
[004.164]: STATE <-- SAHARA_WAIT_DONE_RESP
[004.164]: RECEIVED <-- SAHARA_DONE_RESP_ID
[004.164]: image_tx_status = 1
[004.164]: Successfully uploaded all images
[004.164]: Sahara protocol completed
[004.165]: dir=/mnt/RM500QGLAAR01A01M4G_BETA_20200428F_factory/update/firehose
[004.165]: d_name=rawprogram_nand_p4K_b256K_factory.xml
[005.185]: <log value="INFO: Binary build date: Apr 19 2020 @ 17:49:11" />
[005.185]: <log value="INFO: Binary build date: Apr 19 2020 @ 17:49:11." />
[005.185]: <log value="INFO: Chip serial num: 0 (0x0)" />
[005.186]: <log value="INFO: Supported Functions (15):" />
[005.186]: <log value="INFO: program" />
[005.187]: <log value="INFO: read" />
[005.187]: <log value="INFO: nop" />
[005.187]: <log value="INFO: patch" />
[005.188]: <log value="INFO: configure" />
[005.188]: <log value="INFO: setbootablestoragedrive" />
[005.188]: <log value="INFO: erase" />
[005.188]: <log value="INFO: power" />
[005.189]: <log value="INFO: firmwarewrite" />
[005.189]: <log value="INFO: getstorageinfo" />
[005.189]: <log value="INFO: benchmark" />
[005.190]: <log value="INFO: emmc" />
[005.190]: <log value="INFO: ufs" />
[005.190]: <log value="INFO: fixgpt" />
[005.191]: <log value="INFO: getsha256digest" />
[005.191]: <log value="INFO: End of supported functions 15" />
[006.182]: inf[0] ep_in -1/1024, errno = 110 (Operation timed out), timeout=1000
[006.182]: qusb_noblock_read read=0, errno: 110 (Operation timed out)
[006.182]: qusb_noblock_read cur=0, min_size=1
[006.182]: firehose_protocol.c fh_recv_cmd 327 fail
[006.183]: <configure MemoryName="nand" Verbose="0" AlwaysValidate="0" MaxDigestTableSizeInBytes="2048" MaxPayloadSizeToTargetInBytes="8192" ZlpAwareHost="1" SkipStorageInit="0" />
[006.184]: <log value="INFO: Calling handler for configure" />
[006.184]: <log value="INFO: Storage type set to value nand" />
[006.186]: <response value="ACK" MemoryName="nand" MinVersionSupported="1" Version="1" MaxPayloadSizeToTargetInBytes="8192" MaxPayloadSizeToTargetInBytesSupported="8192" MaxXMLSizeInBytes="4096" DateTime="Apr 19 2020 - 17:49:11" />
[006.186]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="640" physical_partition_number="0" start_sector="0" />
[006.187]: <log value="INFO: Calling handler for erase" />
[006.256]: <log value="INFO: [296] bbt_size:100 blocks:800." />
[006.256]: <log value="INFO: [298] bbt_size:100 blocks:800." />
[006.645]: <log value="INFO: Erasing start sector 0, num sectors 0" />
[006.653]: <response value="ACK" rawmode="false" />
[006.654]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="256" physical_partition_number="0" start_sector="640" />
[006.656]: <log value="INFO: Calling handler for erase" />
[006.657]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.658]: <log value="INFO: Erasing start sector 640, num sectors 0" />
[006.660]: <response value="ACK" rawmode="false" />
[006.661]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="5632" physical_partition_number="0" start_sector="896" />
[006.662]: <log value="INFO: Calling handler for erase" />
[006.663]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.665]: <log value="INFO: Erasing start sector 896, num sectors 0" />
[006.807]: <response value="ACK" rawmode="false" />
[006.807]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="512" physical_partition_number="0" start_sector="8704" />
[006.808]: <log value="INFO: Calling handler for erase" />
[006.810]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.811]: <log value="INFO: Erasing start sector 8704, num sectors 0" />
[006.818]: <response value="ACK" rawmode="false" />
[006.819]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="320" physical_partition_number="0" start_sector="9216" />
[006.820]: <log value="INFO: Calling handler for erase" />
[006.821]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.822]: <log value="INFO: Erasing start sector 9216, num sectors 0" />
[006.825]: <response value="ACK" rawmode="false" />
[006.826]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="320" physical_partition_number="0" start_sector="9856" />
[006.827]: <log value="INFO: Calling handler for erase" />
[006.828]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.829]: <log value="INFO: Erasing start sector 9856, num sectors 0" />
[006.832]: <response value="ACK" rawmode="false" />
[006.833]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="320" physical_partition_number="0" start_sector="10176" />
[006.834]: <log value="INFO: Calling handler for erase" />
[006.835]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.835]: <log value="INFO: Erasing start sector 10176, num sectors 0" />
[006.839]: <response value="ACK" rawmode="false" />
[006.840]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="320" physical_partition_number="0" start_sector="10496" />
[006.841]: <log value="INFO: Calling handler for erase" />
[006.842]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.843]: <log value="INFO: Erasing start sector 10496, num sectors 0" />
[006.846]: <response value="ACK" rawmode="false" />
[006.847]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="320" physical_partition_number="0" start_sector="10816" />
[006.848]: <log value="INFO: Calling handler for erase" />
[006.848]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.849]: <log value="INFO: Erasing start sector 10816, num sectors 0" />
[006.853]: <response value="ACK" rawmode="false" />
[006.854]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="320" physical_partition_number="0" start_sector="11136" />
[006.855]: <log value="INFO: Calling handler for erase" />
[006.856]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.856]: <log value="INFO: Erasing start sector 11136, num sectors 0" />
[006.860]: <response value="ACK" rawmode="false" />
[006.861]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="320" physical_partition_number="0" start_sector="11456" />
[006.862]: <log value="INFO: Calling handler for erase" />
[006.863]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.864]: <log value="INFO: Erasing start sector 11456, num sectors 0" />
[006.867]: <response value="ACK" rawmode="false" />
[006.868]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="640" physical_partition_number="0" start_sector="11776" />
[006.869]: <log value="INFO: Calling handler for erase" />
[006.870]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.871]: <log value="INFO: Erasing start sector 11776, num sectors 0" />
[006.880]: <response value="ACK" rawmode="false" />
[006.880]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="320" physical_partition_number="0" start_sector="12416" />
[006.881]: <log value="INFO: Calling handler for erase" />
[006.882]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.883]: <log value="INFO: Erasing start sector 12416, num sectors 0" />
[006.887]: <response value="ACK" rawmode="false" />
[006.888]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="320" physical_partition_number="0" start_sector="13376" />
[006.889]: <log value="INFO: Calling handler for erase" />
[006.889]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.890]: <log value="INFO: Erasing start sector 13376, num sectors 0" />
[006.894]: <response value="ACK" rawmode="false" />
[006.894]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="3584" physical_partition_number="0" start_sector="13696" />
[006.895]: <log value="INFO: Calling handler for erase" />
[006.896]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.897]: <log value="INFO: Erasing start sector 13696, num sectors 0" />
[006.953]: <response value="ACK" rawmode="false" />
[006.953]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="3584" physical_partition_number="0" start_sector="17280" />
[006.955]: <log value="INFO: Calling handler for erase" />
[006.955]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[006.956]: <log value="INFO: Erasing start sector 17280, num sectors 0" />
[007.014]: <response value="ACK" rawmode="false" />
[007.014]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="28928" physical_partition_number="0" start_sector="27456" />
[007.016]: <log value="INFO: Calling handler for erase" />
[007.016]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[007.017]: <log value="INFO: Erasing start sector 27456, num sectors 0" />
[007.548]: <response value="ACK" rawmode="false" />
[007.548]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="5120" physical_partition_number="0" start_sector="56384" />
[007.550]: <log value="INFO: Calling handler for erase" />
[007.550]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[007.551]: <log value="INFO: Erasing start sector 56384, num sectors 0" />
[007.628]: <response value="ACK" rawmode="false" />
[007.628]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="32000" physical_partition_number="0" start_sector="61504" />
[007.629]: <log value="INFO: Calling handler for erase" />
[007.630]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[007.631]: <log value="INFO: Erasing start sector 61504, num sectors 0" />
[008.119]: <response value="ACK" rawmode="false" />
[008.119]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="9216" physical_partition_number="0" start_sector="93504" />
[008.120]: <log value="INFO: Calling handler for erase" />
[008.121]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.122]: <log value="INFO: Erasing start sector 93504, num sectors 0" />
[008.228]: <response value="ACK" rawmode="false" />
[008.229]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="28352" physical_partition_number="0" start_sector="102720" />
[008.230]: <log value="INFO: Calling handler for erase" />
[008.230]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.231]: <log value="INFO: Erasing start sector 102720, num sectors 0" />
[008.739]: <response value="ACK" rawmode="false" />
[008.739]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="partition_complete_p4K_b256K.mbn" num_partition_sectors="4" physical_partition_number="0" start_sector="640" />
[008.740]: <log value="INFO: Calling handler for program" />
[008.741]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.742]: <response value="ACK" rawmode="true" />
[008.742]: send partition_complete_p4K_b256K.mbn, filesize=16384
.
[008.748]: upgrade progress 0% 16384/191864239
[008.749]: send finished
[008.750]: <response value="ACK" rawmode="false" />
[008.751]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\cefs.mbn" num_partition_sectors="446" physical_partition_number="0" start_sector="896" />
[008.752]: <log value="INFO: Calling handler for program" />
[008.752]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.753]: <response value="ACK" rawmode="true" />
[008.754]: send ../cefs.mbn, filesize=1826816
.......................
[009.198]: upgrade progress 0% 1843200/191864239
[009.198]: send finished
[009.200]: <response value="ACK" rawmode="false" />
[009.200]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\tz.mbn" num_partition_sectors="223" physical_partition_number="0" start_sector="8704" />
[009.201]: <log value="INFO: Calling handler for program" />
[009.202]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.203]: <response value="ACK" rawmode="true" />
[009.203]: send ../tz.mbn, filesize=913408
............
[009.430]: upgrade progress 1% 2756608/191864239
[009.430]: send finished
[009.431]: <response value="ACK" rawmode="false" />
[009.431]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\devcfg.mbn" num_partition_sectors="11" physical_partition_number="0" start_sector="9216" />
[009.432]: <log value="INFO: Calling handler for program" />
[009.433]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.434]: <response value="ACK" rawmode="true" />
[009.434]: send ../devcfg.mbn, filesize=42379
.
[009.455]: upgrade progress 1% 2798987/191864239
[009.456]: send finished
[009.456]: <response value="ACK" rawmode="false" />
[009.457]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\apdp.mbn" num_partition_sectors="4" physical_partition_number="0" start_sector="9856" />
[009.458]: <log value="INFO: Calling handler for program" />
[009.459]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.459]: <response value="ACK" rawmode="true" />
[009.460]: send ../apdp.mbn, filesize=13508
.
[009.466]: upgrade progress 1% 2812495/191864239
[009.466]: send finished
[009.468]: <response value="ACK" rawmode="false" />
[009.468]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\xbl_cfg.elf" num_partition_sectors="17" physical_partition_number="0" start_sector="10176" />
[009.469]: <log value="INFO: Calling handler for program" />
[009.470]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.471]: <response value="ACK" rawmode="true" />
[009.471]: send ../xbl_cfg.elf, filesize=65724
.
[009.498]: upgrade progress 1% 2878219/191864239
[009.498]: send finished
[009.499]: <response value="ACK" rawmode="false" />
[009.500]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\multi_image.mbn" num_partition_sectors="4" physical_partition_number="0" start_sector="10496" />
[009.501]: <log value="INFO: Calling handler for program" />
[009.501]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.502]: <response value="ACK" rawmode="true" />
[009.503]: send ../multi_image.mbn, filesize=13008
.
[009.515]: upgrade progress 1% 2891227/191864239
[009.516]: send finished
[009.517]: <response value="ACK" rawmode="false" />
[009.518]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\hyp.mbn" num_partition_sectors="21" physical_partition_number="0" start_sector="11136" />
[009.519]: <log value="INFO: Calling handler for program" />
[009.520]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.520]: <response value="ACK" rawmode="true" />
[009.521]: send ../hyp.mbn, filesize=84416
..
[009.547]: upgrade progress 1% 2975643/191864239
[009.547]: send finished
[009.548]: <response value="ACK" rawmode="false" />
[009.549]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\abl.elf" num_partition_sectors="43" physical_partition_number="0" start_sector="11456" />
[009.550]: <log value="INFO: Calling handler for program" />
[009.551]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.551]: <response value="ACK" rawmode="true" />
[009.552]: send ../abl.elf, filesize=176128
...
[009.599]: upgrade progress 1% 3151771/191864239
[009.599]: send finished
[009.600]: <response value="ACK" rawmode="false" />
[009.601]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\uefi.elf" num_partition_sectors="291" physical_partition_number="0" start_sector="11776" />
[009.602]: <log value="INFO: Calling handler for program" />
[009.603]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.603]: <response value="ACK" rawmode="true" />
[009.604]: send ../uefi.elf, filesize=1191936
...............
[009.897]: upgrade progress 2% 4343707/191864239
[009.897]: send finished
[009.898]: <response value="ACK" rawmode="false" />
[009.898]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\tools.fv" num_partition_sectors="96" physical_partition_number="0" start_sector="12416" />
[009.899]: <log value="INFO: Calling handler for program" />
[009.900]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.901]: <response value="ACK" rawmode="true" />
[009.901]: send ../tools.fv, filesize=393216
.....
[009.995]: upgrade progress 2% 4736923/191864239
[009.995]: send finished
[009.997]: <response value="ACK" rawmode="false" />
[009.997]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sdxprairie-boot.img" num_partition_sectors="2530" physical_partition_number="0" start_sector="13696" />
[009.998]: <log value="INFO: Calling handler for program" />
[009.999]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[010.000]: <response value="ACK" rawmode="true" />
[010.000]: send ../sdxprairie-boot.img, filesize=10360832
...............................................................................................................................
[012.503]: upgrade progress 7% 15097755/191864239
[012.504]: send finished
[012.505]: <response value="ACK" rawmode="false" />
[012.506]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sdxprairie-boot.img" num_partition_sectors="2530" physical_partition_number="0" start_sector="17280" />
[012.507]: <log value="INFO: Calling handler for program" />
[012.508]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[012.508]: <response value="ACK" rawmode="true" />
[012.509]: send ../sdxprairie-boot.img, filesize=10360832
...............................................................................................................................
[014.934]: upgrade progress 13% 25458587/191864239
[014.935]: send finished
[014.936]: <response value="ACK" rawmode="false" />
[014.937]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\NON-HLOS.ubi" num_partition_sectors="18624" physical_partition_number="0" start_sector="27456" />
[014.938]: <log value="INFO: Calling handler for program" />
[014.939]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[014.939]: <response value="ACK" rawmode="true" />
[014.940]: send ../NON-HLOS.ubi, filesize=76283904
....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
[034.852]: upgrade progress 53% 101742491/191864239
[034.852]: send finished
[034.854]: <response value="ACK" rawmode="false" />
[034.855]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sdxprairie-recoveryfs.ubi" num_partition_sectors="3520" physical_partition_number="0" start_sector="56384" />
[034.856]: <log value="INFO: Calling handler for program" />
[034.857]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[034.857]: <response value="ACK" rawmode="true" />
[034.858]: send ../sdxprairie-recoveryfs.ubi, filesize=14417920
................................................................................................................................................................................
[038.365]: upgrade progress 60% 116160411/191864239
[038.365]: send finished
[038.367]: <response value="ACK" rawmode="false" />
[038.367]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\usrdata.ubi" num_partition_sectors="960" physical_partition_number="0" start_sector="61504" />
[038.368]: <log value="INFO: Calling handler for program" />
[038.369]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[038.370]: <response value="ACK" rawmode="true" />
[038.370]: send ../usrdata.ubi, filesize=3932160
................................................
[039.286]: upgrade progress 62% 120092571/191864239
[039.287]: send finished
[039.288]: <response value="ACK" rawmode="false" />
[039.289]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\oemdata.ubi" num_partition_sectors="960" physical_partition_number="0" start_sector="93504" />
[039.290]: <log value="INFO: Calling handler for program" />
[039.291]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[039.291]: <response value="ACK" rawmode="true" />
[039.292]: send ../oemdata.ubi, filesize=3932160
................................................
[040.219]: upgrade progress 64% 124024731/191864239
[040.220]: send finished
[040.221]: <response value="ACK" rawmode="false" />
[040.222]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sdxprairie-sysfs.ubi" num_partition_sectors="16384" physical_partition_number="0" start_sector="102720" />
[040.223]: <log value="INFO: Calling handler for program" />
[040.224]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[040.224]: <response value="ACK" rawmode="true" />
[040.225]: send ../sdxprairie-sysfs.ubi, filesize=67108864
....................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
[057.600]: upgrade progress 99% 191133595/191864239
[057.600]: send finished
[057.602]: <response value="ACK" rawmode="false" />
[057.602]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\aop.mbn" num_partition_sectors="38" physical_partition_number="0" start_sector="10816" />
[057.603]: <log value="INFO: Calling handler for program" />
[057.604]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[057.605]: <response value="ACK" rawmode="true" />
[057.605]: send ../aop.mbn, filesize=154240
..
[057.647]: upgrade progress 100% 191864239/191864239
[057.647]: send finished
[057.648]: <response value="ACK" rawmode="false" />
[057.649]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sbl1.mbn" num_partition_sectors="141" physical_partition_number="0" start_sector="0" />
[057.650]: <log value="INFO: Calling handler for program" />
[057.651]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[057.651]: <response value="ACK" rawmode="true" />
[057.652]: send ../sbl1.mbn, filesize=576404
........
[057.789]: upgrade progress 100% 192440643/191864239
[057.789]: send finished
[057.790]: <response value="ACK" rawmode="false" />
[057.790]: <power value="reset" />
[057.791]: <log value="INFO: Calling handler for power" />
[057.791]: <response value="ACK" rawmode="false" />
[057.792]: <log value="INFO: Will issue reset/power off 100 useconds, if this hangs check if watchdog is enabled" />
[057.792]: <log value="INFO: bsp_target_reset() 1" />
[057.800]: inf[0] ep_in -1/1024, errno = 71 (Protocol error)
[057.800]: qusb_noblock_read read=-1, errno: 71 (Protocol error)
[057.800]: qusb_noblock_read cur=0, min_size=1
[057.800]: firehose_protocol.c fh_recv_cmd 327 fail
[057.800]: THE TOTAL DOWNLOAD TIME IS 53.750 s
[057.801]: Upgrade module successfully.
root@OpenWrt:~#

View File

@ -0,0 +1,38 @@
root@OpenWrt:~# ./QFirehose -p 9008
[000.000]: QFirehose Version: Quectel_LTE&5G_QFirehose_Linux&Android_V1.3.2
[000.000]: Builded: May 18 2020 11:32:04
[000.004]: [1] /sys/bus/usb/devices/2-1.4 2c7c/800/414
[000.012]: P: /dev/bus/usb/002/005 idVendor=2c7c idProduct=0800
[000.012]: C: /dev/bus/usb/002/005 bNumInterfaces: 5
[000.014]: I: If#= 0 Alt= 0 #EPs= 2 Cls=ff Sub=ff Prot=30
[000.015]: E: Ad=81 Atr=02 MxPS= 1024 Ivl=0ms
[000.015]: E: Ad=01 Atr=02 MxPS= 1024 Ivl=0ms
[000.016]: I: If#= 1 Alt= 0 #EPs= 3 Cls=ff Sub=00 Prot=00
[000.017]: I: If#= 2 Alt= 0 #EPs= 3 Cls=ff Sub=00 Prot=00
[000.018]: I: If#= 3 Alt= 0 #EPs= 3 Cls=ff Sub=00 Prot=00
[000.019]: I: If#= 4 Alt= 0 #EPs= 3 Cls=ff Sub=ff Prot=ff
[000.021]: qusb_noblock_open port_name = /dev/ttyUSB0
[000.024]: old software version: RM500QGLAAR01A01M4G_BETA_20200428F
[001.025]: poll_wait events=POLLIN msec=1000 timeout
[001.026]: qusb_noblock_read cur=0, min_size=1
[001.026]: switch to 'Emergency download mode'
[001.031]: successful, wait module reboot
[002.034]: fail to fopen /sys/bus/usb/devices/2-1.4/uevent, errno: 2 (No such file or directory)
[003.038]: fail to fopen /sys/bus/usb/devices/2-1.4/uevent, errno: 2 (No such file or directory)
[004.041]: [1] /sys/bus/usb/devices/1-1.4 5c6/9008/0
[004.046]: P: /dev/bus/usb/001/010 idVendor=05c6 idProduct=9008
[004.046]: C: /dev/bus/usb/001/010 bNumInterfaces: 1
[004.047]: I: If#= 0 Alt= 0 #EPs= 2 Cls=ff Sub=ff Prot=11
[004.048]: E: Ad=81 Atr=02 MxPS= 512 Ivl=0ms
[004.049]: E: Ad=01 Atr=02 MxPS= 512 Ivl=0ms
[004.052]: create_tcp_server tcp_port=9008
[004.053]: server_fd=4
[004.055]: wait_client_connect
[023.889]: clientfd = 5 192.168.1.153:58069 connect
[023.889]: usb_fd = 6
[083.310]: inf[0] ep_in -1/4096, errno = 71 (Protocol error)
[083.310]: qusb_noblock_read read=-1, errno: 71 (Protocol error)
[083.310]: qusb_noblock_read cur=0, min_size=1
[083.310]: usb2tcp_main poll usb_fd = 6, revents = 0011
root@OpenWrt:~#

View File

@ -0,0 +1,607 @@
carl@carl-Lenovo-ideapad-110-15ISK:~/Qfirehose_linux$ ./qfirehose -f ../EM20GRAR01A04V01M4G_factory -p 172.18.112.13:9008
[000.000] QFirehose Version: LTE_QFirehose_Linux&Android_V1.1.8
[000.000] Builded: Jul 5 2019 12:04:58
[000.000] Find md5 check file <../EM20GRAR01A04V01M4G_factory/md5.txt>
[000.000] Totals checking 0 files md5 value, 0 file fail!
[000.001] qtcp_connect port_name = 172.18.112.13:9008
[000.006] idVendor=2c7c, idProduct=0620, interfaceNum=6
[001.008] poll_wait events=POLLIN msec=1000 timeout
[001.008] qusb_noblock_read cur=0, min_size=1
[001.008] switch to 'Emergency download mode'
[001.011] successful, wait module reboot
[002.011] qtcp_connect port_name = 172.18.112.13:9008
[002.014] idVendor=05c6, idProduct=9008, interfaceNum=1
[002.014] dir=../EM20GRAR01A04V01M4G_factory/update/firehose
[002.014] dir=../EM20GRAR01A04V01M4G_factory/update/firehose
[002.014] d_name=prog_firehose_sdx24.mbn
[002.014] prog_nand_firehose_filename = prog_firehose_sdx24.mbn
[002.015] STATE <-- SAHARA_WAIT_HELLO
[002.015] RECEIVED <-- SAHARA_HELLO_ID
[002.015] RECEIVED <-- SAHARA_MODE_IMAGE_TX_PENDING
[002.015] SENDING --> SAHARA_HELLO_RESPONSE
[002.015] STATE <-- SAHARA_WAIT_COMMAND
[002.052] RECEIVED <-- SAHARA_READ_DATA_ID
[002.052] 0x0000000d 0x00000000 0x00000034
[002.052] STATE <-- SAHARA_WAIT_COMMAND
[002.121] RECEIVED <-- SAHARA_READ_DATA_ID
[002.121] 0x0000000d 0x00000034 0x00000080
[002.121] STATE <-- SAHARA_WAIT_COMMAND
[002.193] RECEIVED <-- SAHARA_READ_DATA_ID
[002.193] 0x0000000d 0x00001000 0x00001000
[002.193] STATE <-- SAHARA_WAIT_COMMAND
[002.232] RECEIVED <-- SAHARA_READ_DATA_ID
[002.232] 0x0000000d 0x00002000 0x000009d0
[002.233] STATE <-- SAHARA_WAIT_COMMAND
[002.272] RECEIVED <-- SAHARA_READ_DATA_ID
[002.272] 0x0000000d 0x00003000 0x00001000
[002.273] STATE <-- SAHARA_WAIT_COMMAND
[002.312] RECEIVED <-- SAHARA_READ_DATA_ID
[002.312] 0x0000000d 0x00004000 0x00001000
[002.313] STATE <-- SAHARA_WAIT_COMMAND
[002.353] RECEIVED <-- SAHARA_READ_DATA_ID
[002.353] 0x0000000d 0x00005000 0x00001000
[002.353] STATE <-- SAHARA_WAIT_COMMAND
[002.392] RECEIVED <-- SAHARA_READ_DATA_ID
[002.392] 0x0000000d 0x00006000 0x00001000
[002.392] STATE <-- SAHARA_WAIT_COMMAND
[002.432] RECEIVED <-- SAHARA_READ_DATA_ID
[002.432] 0x0000000d 0x00007000 0x00001000
[002.433] STATE <-- SAHARA_WAIT_COMMAND
[002.473] RECEIVED <-- SAHARA_READ_DATA_ID
[002.473] 0x0000000d 0x00008000 0x00001000
[002.473] STATE <-- SAHARA_WAIT_COMMAND
[002.513] RECEIVED <-- SAHARA_READ_DATA_ID
[002.513] 0x0000000d 0x00009000 0x00001000
[002.513] STATE <-- SAHARA_WAIT_COMMAND
[002.552] RECEIVED <-- SAHARA_READ_DATA_ID
[002.552] 0x0000000d 0x0000a000 0x00001000
[002.553] STATE <-- SAHARA_WAIT_COMMAND
[002.592] RECEIVED <-- SAHARA_READ_DATA_ID
[002.592] 0x0000000d 0x0000b000 0x00001000
[002.593] STATE <-- SAHARA_WAIT_COMMAND
[002.633] RECEIVED <-- SAHARA_READ_DATA_ID
[002.633] 0x0000000d 0x0000c000 0x00001000
[002.633] STATE <-- SAHARA_WAIT_COMMAND
[002.673] RECEIVED <-- SAHARA_READ_DATA_ID
[002.673] 0x0000000d 0x0000d000 0x00001000
[002.673] STATE <-- SAHARA_WAIT_COMMAND
[002.712] RECEIVED <-- SAHARA_READ_DATA_ID
[002.713] 0x0000000d 0x0000e000 0x00001000
[002.713] STATE <-- SAHARA_WAIT_COMMAND
[002.756] RECEIVED <-- SAHARA_READ_DATA_ID
[002.757] 0x0000000d 0x0000f000 0x00001000
[002.757] STATE <-- SAHARA_WAIT_COMMAND
[002.796] RECEIVED <-- SAHARA_READ_DATA_ID
[002.796] 0x0000000d 0x00010000 0x00001000
[002.796] STATE <-- SAHARA_WAIT_COMMAND
[002.837] RECEIVED <-- SAHARA_READ_DATA_ID
[002.837] 0x0000000d 0x00011000 0x00001000
[002.837] STATE <-- SAHARA_WAIT_COMMAND
[002.876] RECEIVED <-- SAHARA_READ_DATA_ID
[002.876] 0x0000000d 0x00012000 0x00001000
[002.877] STATE <-- SAHARA_WAIT_COMMAND
[002.916] RECEIVED <-- SAHARA_READ_DATA_ID
[002.917] 0x0000000d 0x00013000 0x00001000
[002.917] STATE <-- SAHARA_WAIT_COMMAND
[002.957] RECEIVED <-- SAHARA_READ_DATA_ID
[002.957] 0x0000000d 0x00014000 0x00001000
[002.957] STATE <-- SAHARA_WAIT_COMMAND
[002.997] RECEIVED <-- SAHARA_READ_DATA_ID
[002.997] 0x0000000d 0x00015000 0x00001000
[002.997] STATE <-- SAHARA_WAIT_COMMAND
[003.036] RECEIVED <-- SAHARA_READ_DATA_ID
[003.036] 0x0000000d 0x00016000 0x00001000
[003.037] STATE <-- SAHARA_WAIT_COMMAND
[003.076] RECEIVED <-- SAHARA_READ_DATA_ID
[003.076] 0x0000000d 0x00017000 0x00001000
[003.076] STATE <-- SAHARA_WAIT_COMMAND
[003.117] RECEIVED <-- SAHARA_READ_DATA_ID
[003.117] 0x0000000d 0x00018000 0x00001000
[003.117] STATE <-- SAHARA_WAIT_COMMAND
[003.157] RECEIVED <-- SAHARA_READ_DATA_ID
[003.157] 0x0000000d 0x00019000 0x00001000
[003.157] STATE <-- SAHARA_WAIT_COMMAND
[003.196] RECEIVED <-- SAHARA_READ_DATA_ID
[003.197] 0x0000000d 0x0001a000 0x00001000
[003.197] STATE <-- SAHARA_WAIT_COMMAND
[003.236] RECEIVED <-- SAHARA_READ_DATA_ID
[003.236] 0x0000000d 0x0001b000 0x00001000
[003.237] STATE <-- SAHARA_WAIT_COMMAND
[003.276] RECEIVED <-- SAHARA_READ_DATA_ID
[003.276] 0x0000000d 0x0001c000 0x00001000
[003.277] STATE <-- SAHARA_WAIT_COMMAND
[003.317] RECEIVED <-- SAHARA_READ_DATA_ID
[003.317] 0x0000000d 0x0001d000 0x00001000
[003.317] STATE <-- SAHARA_WAIT_COMMAND
[003.356] RECEIVED <-- SAHARA_READ_DATA_ID
[003.356] 0x0000000d 0x0001e000 0x00001000
[003.357] STATE <-- SAHARA_WAIT_COMMAND
[003.396] RECEIVED <-- SAHARA_READ_DATA_ID
[003.396] 0x0000000d 0x0001f000 0x00001000
[003.397] STATE <-- SAHARA_WAIT_COMMAND
[003.437] RECEIVED <-- SAHARA_READ_DATA_ID
[003.437] 0x0000000d 0x00020000 0x00001000
[003.437] STATE <-- SAHARA_WAIT_COMMAND
[003.476] RECEIVED <-- SAHARA_READ_DATA_ID
[003.477] 0x0000000d 0x00021000 0x00001000
[003.477] STATE <-- SAHARA_WAIT_COMMAND
[003.516] RECEIVED <-- SAHARA_READ_DATA_ID
[003.517] 0x0000000d 0x00022000 0x00001000
[003.517] STATE <-- SAHARA_WAIT_COMMAND
[003.556] RECEIVED <-- SAHARA_READ_DATA_ID
[003.556] 0x0000000d 0x00023000 0x00001000
[003.557] STATE <-- SAHARA_WAIT_COMMAND
[003.597] RECEIVED <-- SAHARA_READ_DATA_ID
[003.597] 0x0000000d 0x00024000 0x00001000
[003.597] STATE <-- SAHARA_WAIT_COMMAND
[003.637] RECEIVED <-- SAHARA_READ_DATA_ID
[003.637] 0x0000000d 0x00025000 0x00001000
[003.637] STATE <-- SAHARA_WAIT_COMMAND
[003.676] RECEIVED <-- SAHARA_READ_DATA_ID
[003.676] 0x0000000d 0x00026000 0x00001000
[003.677] STATE <-- SAHARA_WAIT_COMMAND
[003.716] RECEIVED <-- SAHARA_READ_DATA_ID
[003.716] 0x0000000d 0x00027000 0x00001000
[003.717] STATE <-- SAHARA_WAIT_COMMAND
[003.757] RECEIVED <-- SAHARA_READ_DATA_ID
[003.757] 0x0000000d 0x00028000 0x00001000
[003.757] STATE <-- SAHARA_WAIT_COMMAND
[003.797] RECEIVED <-- SAHARA_READ_DATA_ID
[003.797] 0x0000000d 0x00029000 0x00001000
[003.797] STATE <-- SAHARA_WAIT_COMMAND
[003.836] RECEIVED <-- SAHARA_READ_DATA_ID
[003.837] 0x0000000d 0x0002a000 0x000005a8
[003.837] STATE <-- SAHARA_WAIT_COMMAND
[003.876] RECEIVED <-- SAHARA_READ_DATA_ID
[003.876] 0x0000000d 0x0002a600 0x00001000
[003.877] STATE <-- SAHARA_WAIT_COMMAND
[003.917] RECEIVED <-- SAHARA_READ_DATA_ID
[003.917] 0x0000000d 0x0002b600 0x00001000
[003.917] STATE <-- SAHARA_WAIT_COMMAND
[003.957] RECEIVED <-- SAHARA_READ_DATA_ID
[003.957] 0x0000000d 0x0002c600 0x00001000
[003.957] STATE <-- SAHARA_WAIT_COMMAND
[003.996] RECEIVED <-- SAHARA_READ_DATA_ID
[003.997] 0x0000000d 0x0002d600 0x00001000
[003.997] STATE <-- SAHARA_WAIT_COMMAND
[004.036] RECEIVED <-- SAHARA_READ_DATA_ID
[004.036] 0x0000000d 0x0002e600 0x00001000
[004.036] STATE <-- SAHARA_WAIT_COMMAND
[004.076] RECEIVED <-- SAHARA_READ_DATA_ID
[004.077] 0x0000000d 0x0002f600 0x00001000
[004.077] STATE <-- SAHARA_WAIT_COMMAND
[004.116] RECEIVED <-- SAHARA_READ_DATA_ID
[004.117] 0x0000000d 0x00030600 0x00001000
[004.117] STATE <-- SAHARA_WAIT_COMMAND
[004.156] RECEIVED <-- SAHARA_READ_DATA_ID
[004.156] 0x0000000d 0x00031600 0x00001000
[004.157] STATE <-- SAHARA_WAIT_COMMAND
[004.196] RECEIVED <-- SAHARA_READ_DATA_ID
[004.196] 0x0000000d 0x00032600 0x00001000
[004.197] STATE <-- SAHARA_WAIT_COMMAND
[004.237] RECEIVED <-- SAHARA_READ_DATA_ID
[004.237] 0x0000000d 0x00033600 0x00001000
[004.237] STATE <-- SAHARA_WAIT_COMMAND
[004.277] RECEIVED <-- SAHARA_READ_DATA_ID
[004.277] 0x0000000d 0x00034600 0x00001000
[004.277] STATE <-- SAHARA_WAIT_COMMAND
[004.316] RECEIVED <-- SAHARA_READ_DATA_ID
[004.316] 0x0000000d 0x00035600 0x00001000
[004.317] STATE <-- SAHARA_WAIT_COMMAND
[004.356] RECEIVED <-- SAHARA_READ_DATA_ID
[004.357] 0x0000000d 0x00036600 0x00001000
[004.357] STATE <-- SAHARA_WAIT_COMMAND
[004.397] RECEIVED <-- SAHARA_READ_DATA_ID
[004.397] 0x0000000d 0x00037600 0x00001000
[004.397] STATE <-- SAHARA_WAIT_COMMAND
[004.437] RECEIVED <-- SAHARA_READ_DATA_ID
[004.437] 0x0000000d 0x00038600 0x00001000
[004.437] STATE <-- SAHARA_WAIT_COMMAND
[004.476] RECEIVED <-- SAHARA_READ_DATA_ID
[004.477] 0x0000000d 0x00039600 0x00001000
[004.477] STATE <-- SAHARA_WAIT_COMMAND
[004.516] RECEIVED <-- SAHARA_READ_DATA_ID
[004.516] 0x0000000d 0x0003a600 0x00001000
[004.516] STATE <-- SAHARA_WAIT_COMMAND
[004.557] RECEIVED <-- SAHARA_READ_DATA_ID
[004.557] 0x0000000d 0x0003b600 0x00001000
[004.557] STATE <-- SAHARA_WAIT_COMMAND
[004.597] RECEIVED <-- SAHARA_READ_DATA_ID
[004.597] 0x0000000d 0x0003c600 0x00001000
[004.597] STATE <-- SAHARA_WAIT_COMMAND
[004.636] RECEIVED <-- SAHARA_READ_DATA_ID
[004.637] 0x0000000d 0x0003d600 0x00001000
[004.637] STATE <-- SAHARA_WAIT_COMMAND
[004.676] RECEIVED <-- SAHARA_READ_DATA_ID
[004.676] 0x0000000d 0x0003e600 0x00001000
[004.677] STATE <-- SAHARA_WAIT_COMMAND
[004.717] RECEIVED <-- SAHARA_READ_DATA_ID
[004.717] 0x0000000d 0x0003f600 0x00001000
[004.717] STATE <-- SAHARA_WAIT_COMMAND
[004.756] RECEIVED <-- SAHARA_READ_DATA_ID
[004.757] 0x0000000d 0x00040600 0x00001000
[004.757] STATE <-- SAHARA_WAIT_COMMAND
[004.796] RECEIVED <-- SAHARA_READ_DATA_ID
[004.797] 0x0000000d 0x00041600 0x00001000
[004.797] STATE <-- SAHARA_WAIT_COMMAND
[004.836] RECEIVED <-- SAHARA_READ_DATA_ID
[004.836] 0x0000000d 0x00042600 0x00001000
[004.837] STATE <-- SAHARA_WAIT_COMMAND
[004.880] RECEIVED <-- SAHARA_END_IMAGE_TX_ID
[004.880] image_id = 13, status = 0
[004.880] SENDING --> SAHARA_DONE
[004.881] STATE <-- SAHARA_WAIT_DONE_RESP
[004.953] RECEIVED <-- SAHARA_DONE_RESP_ID
[004.953] image_tx_status = 1
[004.953] Successfully uploaded all images
[004.953] Sahara protocol completed
[004.953] dir=../EM20GRAR01A04V01M4G_factory/update/firehose
[004.953] d_name=rawprogram_nand_p4K_b256K_factory.xml
[005.934] <log value="INFO: Binary build date: Apr 15 2019 @ 00:24:50" />
[005.935] <log value="INFO: Binary build date: Apr 15 2019 @ 00:24:50." />
[005.935] <log value="INFO: Chip serial num: 0 (0x0)" />
[005.935] <log value="INFO: Supported Functions (15):" />
[005.936] <log value="INFO: program" />
[005.936] <log value="INFO: read" />
[005.936] <log value="INFO: nop" />
[005.936] <log value="INFO: patch" />
[005.936] <log value="INFO: configure" />
[005.936] <log value="INFO: setbootablestoragedrive" />
[005.937] <log value="INFO: erase" />
[005.937] <log value="INFO: power" />
[005.937] <log value="INFO: firmwarewrite" />
[005.937] <log value="INFO: getstorageinfo" />
[005.938] <log value="INFO: benchmark" />
[005.938] <log value="INFO: emmc" />
[005.938] <log value="INFO: ufs" />
[005.938] <log value="INFO: fixgpt" />
[005.938] <log value="INFO: getsha256digest" />
[005.939] <log value="INFO: End of supported functions 15" />
[006.940] poll_wait events=POLLIN msec=1000 timeout
[006.940] qusb_noblock_read cur=0, min_size=1
[006.940] firehose_protocol.c fh_recv_cmd 294 fail
[006.940] <configure MemoryName="nand" Verbose="0" AlwaysValidate="0" MaxDigestTableSizeInBytes="2048" MaxPayloadSizeToTargetInBytes="8192" ZlpAwareHost="1" SkipStorageInit="0" />
[006.974] <log value="INFO: Calling handler for configure" />
[006.975] <log value="INFO: Storage type set to value nand" />
[006.976] <response value="ACK" MemoryName="nand" MinVersionSupported="1" Version="1" MaxPayloadSizeToTargetInBytes="8192" MaxPayloadSizeToTargetInBytesSupported="8192" MaxXMLSizeInBytes="4096" DateTime="Apr 15 2019 - 00:24:50" />
[006.976] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="640" physical_partition_number="0" start_sector="0" />
[007.053] <log value="INFO: Calling handler for erase" />
[007.159] <log value="INFO: [295] bbt_size:100 blocks:800." />
[007.159] <log value="INFO: [297] bbt_size:100 blocks:800." />
[007.521] <log value="INFO: Erasing start sector 0, num sectors 0" />
[007.530] <response value="ACK" rawmode="false" />
[007.530] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="640" physical_partition_number="0" start_sector="640" />
[007.601] <log value="INFO: Calling handler for erase" />
[007.601] <log value="INFO: NAND was previously open, returning existing handle 0." />
[007.601] <log value="INFO: Erasing start sector 640, num sectors 0" />
[007.601] <response value="ACK" rawmode="false" />
[007.601] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="5632" physical_partition_number="0" start_sector="1280" />
[007.673] <log value="INFO: Calling handler for erase" />
[007.673] <log value="INFO: NAND was previously open, returning existing handle 0." />
[007.673] <log value="INFO: Erasing start sector 1280, num sectors 0" />
[007.722] <response value="ACK" rawmode="false" />
[007.722] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="448" physical_partition_number="0" start_sector="9600" />
[007.793] <log value="INFO: Calling handler for erase" />
[007.793] <log value="INFO: NAND was previously open, returning existing handle 0." />
[007.793] <log value="INFO: Erasing start sector 9600, num sectors 0" />
[007.793] <response value="ACK" rawmode="false" />
[007.793] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="256" physical_partition_number="0" start_sector="10048" />
[007.873] <log value="INFO: Calling handler for erase" />
[007.873] <log value="INFO: NAND was previously open, returning existing handle 0." />
[007.873] <log value="INFO: Erasing start sector 10048, num sectors 0" />
[007.873] <response value="ACK" rawmode="false" />
[007.873] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="256" physical_partition_number="0" start_sector="10944" />
[007.953] <log value="INFO: Calling handler for erase" />
[007.953] <log value="INFO: NAND was previously open, returning existing handle 0." />
[007.953] <log value="INFO: Erasing start sector 10944, num sectors 0" />
[007.953] <response value="ACK" rawmode="false" />
[007.953] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="256" physical_partition_number="0" start_sector="11200" />
[008.033] <log value="INFO: Calling handler for erase" />
[008.033] <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.033] <log value="INFO: Erasing start sector 11200, num sectors 0" />
[008.033] <response value="ACK" rawmode="false" />
[008.033] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="256" physical_partition_number="0" start_sector="11456" />
[008.113] <log value="INFO: Calling handler for erase" />
[008.113] <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.113] <log value="INFO: Erasing start sector 11456, num sectors 0" />
[008.113] <response value="ACK" rawmode="false" />
[008.113] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="256" physical_partition_number="0" start_sector="11712" />
[008.193] <log value="INFO: Calling handler for erase" />
[008.193] <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.193] <log value="INFO: Erasing start sector 11712, num sectors 0" />
[008.193] <response value="ACK" rawmode="false" />
[008.193] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="256" physical_partition_number="0" start_sector="11968" />
[008.273] <log value="INFO: Calling handler for erase" />
[008.273] <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.273] <log value="INFO: Erasing start sector 11968, num sectors 0" />
[008.273] <response value="ACK" rawmode="false" />
[008.273] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="640" physical_partition_number="0" start_sector="12224" />
[008.353] <log value="INFO: Calling handler for erase" />
[008.353] <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.353] <log value="INFO: Erasing start sector 12224, num sectors 0" />
[008.353] <response value="ACK" rawmode="false" />
[008.353] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="384" physical_partition_number="0" start_sector="12864" />
[008.433] <log value="INFO: Calling handler for erase" />
[008.433] <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.433] <log value="INFO: Erasing start sector 12864, num sectors 0" />
[008.433] <response value="ACK" rawmode="false" />
[008.433] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="256" physical_partition_number="0" start_sector="14016" />
[008.513] <log value="INFO: Calling handler for erase" />
[008.513] <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.513] <log value="INFO: Erasing start sector 14016, num sectors 0" />
[008.513] <response value="ACK" rawmode="false" />
[008.513] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="3072" physical_partition_number="0" start_sector="14272" />
[008.593] <log value="INFO: Calling handler for erase" />
[008.593] <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.593] <log value="INFO: Erasing start sector 14272, num sectors 0" />
[008.616] <response value="ACK" rawmode="false" />
[008.616] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="3072" physical_partition_number="0" start_sector="17344" />
[008.693] <log value="INFO: Calling handler for erase" />
[008.693] <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.693] <log value="INFO: Erasing start sector 17344, num sectors 0" />
[008.717] <response value="ACK" rawmode="false" />
[008.717] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="23808" physical_partition_number="0" start_sector="27136" />
[008.793] <log value="INFO: Calling handler for erase" />
[008.793] <log value="INFO: NAND was previously open, returning existing handle 0." />
[008.793] <log value="INFO: Erasing start sector 27136, num sectors 0" />
[009.236] <response value="ACK" rawmode="false" />
[009.236] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="7872" physical_partition_number="0" start_sector="50944" />
[009.313] <log value="INFO: Calling handler for erase" />
[009.313] <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.313] <log value="INFO: Erasing start sector 50944, num sectors 0" />
[009.416] <response value="ACK" rawmode="false" />
[009.416] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="43520" physical_partition_number="0" start_sector="58816" />
[009.493] <log value="INFO: Calling handler for erase" />
[009.493] <log value="INFO: NAND was previously open, returning existing handle 0." />
[009.493] <log value="INFO: Erasing start sector 58816, num sectors 0" />
[010.094] <response value="ACK" rawmode="false" />
[010.094] <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="28736" physical_partition_number="0" start_sector="102336" />
[010.173] <log value="INFO: Calling handler for erase" />
[010.173] <log value="INFO: NAND was previously open, returning existing handle 0." />
[010.173] <log value="INFO: Erasing start sector 102336, num sectors 0" />
[010.715] <response value="ACK" rawmode="false" />
[010.715] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="partition_complete_p4K_b256K.mbn" num_partition_sectors="4" physical_partition_number="0" start_sector="640" />
[010.793] <log value="INFO: Calling handler for program" />
[010.793] <log value="INFO: NAND was previously open, returning existing handle 0." />
[010.793] <response value="ACK" rawmode="true" />
[010.793] send partition_complete_p4K_b256K.mbn, filesize=16384
[010.793] Upgrade progress: 0
[010.793] send finished
[010.840] <response value="ACK" rawmode="false" />
[010.840] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\cefs.mbn" num_partition_sectors="355" physical_partition_number="0" start_sector="1280" />
[010.913] <log value="INFO: Calling handler for program" />
[010.913] <log value="INFO: NAND was previously open, returning existing handle 0." />
[010.913] <response value="ACK" rawmode="true" />
[010.913] send ../cefs.mbn, filesize=1454080
[011.487] send finished
[011.573] <response value="ACK" rawmode="false" />
[011.573] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\tz.mbn" num_partition_sectors="228" physical_partition_number="0" start_sector="9600" />
[011.653] <log value="INFO: Calling handler for program" />
[011.653] <log value="INFO: NAND was previously open, returning existing handle 0." />
[011.653] <response value="ACK" rawmode="true" />
[011.653] send ../tz.mbn, filesize=933888
[011.697] Upgrade progress: 1
[012.004] send finished
[012.093] <response value="ACK" rawmode="false" />
[012.093] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\devcfg.mbn" num_partition_sectors="10" physical_partition_number="0" start_sector="10048" />
[012.173] <log value="INFO: Calling handler for program" />
[012.173] <log value="INFO: NAND was previously open, returning existing handle 0." />
[012.173] <response value="ACK" rawmode="true" />
[012.173] send ../devcfg.mbn, filesize=40222
[012.173] send finished
[012.233] <response value="ACK" rawmode="false" />
[012.233] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\xbl_cfg.elf" num_partition_sectors="14" physical_partition_number="0" start_sector="10944" />
[012.313] <log value="INFO: Calling handler for program" />
[012.313] <log value="INFO: NAND was previously open, returning existing handle 0." />
[012.313] <response value="ACK" rawmode="true" />
[012.313] send ../xbl_cfg.elf, filesize=53348
[012.315] send finished
[012.377] <response value="ACK" rawmode="false" />
[012.377] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\multi_image.mbn" num_partition_sectors="4" physical_partition_number="0" start_sector="11200" />
[012.453] <log value="INFO: Calling handler for program" />
[012.453] <log value="INFO: NAND was previously open, returning existing handle 0." />
[012.453] <response value="ACK" rawmode="true" />
[012.453] send ../multi_image.mbn, filesize=13064
[012.453] send finished
[012.500] <response value="ACK" rawmode="false" />
[012.501] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\aop.mbn" num_partition_sectors="35" physical_partition_number="0" start_sector="11456" />
[012.573] <log value="INFO: Calling handler for program" />
[012.573] <log value="INFO: NAND was previously open, returning existing handle 0." />
[012.573] <response value="ACK" rawmode="true" />
[012.573] send ../aop.mbn, filesize=142624
[012.593] send finished
[012.676] <response value="ACK" rawmode="false" />
[012.676] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\hyp.mbn" num_partition_sectors="20" physical_partition_number="0" start_sector="11712" />
[012.753] <log value="INFO: Calling handler for program" />
[012.753] <log value="INFO: NAND was previously open, returning existing handle 0." />
[012.753] <response value="ACK" rawmode="true" />
[012.753] send ../hyp.mbn, filesize=80192
[012.759] send finished
[012.829] <response value="ACK" rawmode="false" />
[012.829] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\abl.elf" num_partition_sectors="37" physical_partition_number="0" start_sector="11968" />
[012.901] <log value="INFO: Calling handler for program" />
[012.901] <log value="INFO: NAND was previously open, returning existing handle 0." />
[012.901] <response value="ACK" rawmode="true" />
[012.901] send ../abl.elf, filesize=151552
[012.921] send finished
[013.005] <response value="ACK" rawmode="false" />
[013.005] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\uefi.elf" num_partition_sectors="323" physical_partition_number="0" start_sector="12224" />
[013.081] <log value="INFO: Calling handler for program" />
[013.081] <log value="INFO: NAND was previously open, returning existing handle 0." />
[013.081] <response value="ACK" rawmode="true" />
[013.081] send ../uefi.elf, filesize=1323008
[013.233] Upgrade progress: 2
[013.598] send finished
[013.685] <response value="ACK" rawmode="false" />
[013.685] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\tools.fv" num_partition_sectors="96" physical_partition_number="0" start_sector="12864" />
[013.761] <log value="INFO: Calling handler for program" />
[013.761] <log value="INFO: NAND was previously open, returning existing handle 0." />
[013.761] <response value="ACK" rawmode="true" />
[013.761] send ../tools.fv, filesize=393216
[013.874] send finished
[013.969] <response value="ACK" rawmode="false" />
[013.969] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sec.dat" num_partition_sectors="1" physical_partition_number="0" start_sector="14016" />
[014.041] <log value="INFO: Calling handler for program" />
[014.041] <log value="INFO: NAND was previously open, returning existing handle 0." />
[014.041] <response value="ACK" rawmode="true" />
[014.041] send ../sec.dat, filesize=80
[014.041] send finished
[014.084] <response value="ACK" rawmode="false" />
[014.085] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sdxpoorwills-boot.img" num_partition_sectors="2340" physical_partition_number="0" start_sector="14272" />
[014.161] <log value="INFO: Calling handler for program" />
[014.161] <log value="INFO: NAND was previously open, returning existing handle 0." />
[014.161] <response value="ACK" rawmode="true" />
[014.161] send ../sdxpoorwills-boot.img, filesize=9582592
[014.303] Upgrade progress: 3
[015.019] Upgrade progress: 4
[015.731] Upgrade progress: 5
[016.450] Upgrade progress: 6
[017.173] Upgrade progress: 7
[017.884] Upgrade progress: 8
[018.196] send finished
[018.289] <response value="ACK" rawmode="false" />
[018.289] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sdxpoorwills-boot.img" num_partition_sectors="2340" physical_partition_number="0" start_sector="17344" />
[018.361] <log value="INFO: Calling handler for program" />
[018.361] <log value="INFO: NAND was previously open, returning existing handle 0." />
[018.361] <response value="ACK" rawmode="true" />
[018.361] send ../sdxpoorwills-boot.img, filesize=9582592
[018.722] Upgrade progress: 9
[019.442] Upgrade progress: 10
[020.154] Upgrade progress: 11
[020.874] Upgrade progress: 12
[021.594] Upgrade progress: 13
[022.320] Upgrade progress: 14
[022.397] send finished
[022.488] <response value="ACK" rawmode="false" />
[022.489] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\NON-HLOS.ubi" num_partition_sectors="14784" physical_partition_number="0" start_sector="27136" />
[022.561] <log value="INFO: Calling handler for program" />
[022.561] <log value="INFO: NAND was previously open, returning existing handle 0." />
[022.561] <response value="ACK" rawmode="true" />
[022.561] send ../NON-HLOS.ubi, filesize=60555264
[023.140] Upgrade progress: 15
[023.851] Upgrade progress: 16
[024.566] Upgrade progress: 17
[025.282] Upgrade progress: 18
[026.022] Upgrade progress: 19
[026.734] Upgrade progress: 20
[027.460] Upgrade progress: 21
[028.181] Upgrade progress: 22
[028.903] Upgrade progress: 23
[029.633] Upgrade progress: 24
[030.360] Upgrade progress: 25
[031.085] Upgrade progress: 26
[031.812] Upgrade progress: 27
[032.546] Upgrade progress: 28
[033.278] Upgrade progress: 29
[034.007] Upgrade progress: 30
[034.738] Upgrade progress: 31
[035.481] Upgrade progress: 32
[036.214] Upgrade progress: 33
[036.948] Upgrade progress: 34
[037.683] Upgrade progress: 35
[038.426] Upgrade progress: 36
[039.167] Upgrade progress: 37
[039.902] Upgrade progress: 38
[040.649] Upgrade progress: 39
[041.393] Upgrade progress: 40
[042.135] Upgrade progress: 41
[042.877] Upgrade progress: 42
[043.629] Upgrade progress: 43
[044.378] Upgrade progress: 44
[045.121] Upgrade progress: 45
[045.871] Upgrade progress: 46
[046.627] Upgrade progress: 47
[047.369] Upgrade progress: 48
[048.127] Upgrade progress: 49
[048.881] Upgrade progress: 50
[048.917] send finished
[049.013] <response value="ACK" rawmode="false" />
[049.013] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sdxpoorwills-recoveryfs.ubi" num_partition_sectors="4224" physical_partition_number="0" start_sector="50944" />
[049.093] <log value="INFO: Calling handler for program" />
[049.093] <log value="INFO: NAND was previously open, returning existing handle 0." />
[049.093] <response value="ACK" rawmode="true" />
[049.093] send ../sdxpoorwills-recoveryfs.ubi, filesize=17301504
[049.711] Upgrade progress: 51
[050.425] Upgrade progress: 52
[051.143] Upgrade progress: 53
[051.859] Upgrade progress: 54
[052.577] Upgrade progress: 55
[053.303] Upgrade progress: 56
[054.029] Upgrade progress: 57
[054.743] Upgrade progress: 58
[055.472] Upgrade progress: 59
[056.197] Upgrade progress: 60
[056.421] send finished
[056.517] <response value="ACK" rawmode="false" />
[056.517] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\usrdata.ubi" num_partition_sectors="512" physical_partition_number="0" start_sector="58816" />
[056.593] <log value="INFO: Calling handler for program" />
[056.593] <log value="INFO: NAND was previously open, returning existing handle 0." />
[056.593] <response value="ACK" rawmode="true" />
[056.593] send ../usrdata.ubi, filesize=2097152
[057.025] Upgrade progress: 61
[057.422] send finished
[057.517] <response value="ACK" rawmode="false" />
[057.517] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sdxpoorwills-sysfs.ubi" num_partition_sectors="15680" physical_partition_number="0" start_sector="102336" />
[057.593] <log value="INFO: Calling handler for program" />
[057.593] <log value="INFO: NAND was previously open, returning existing handle 0." />
[057.593] <response value="ACK" rawmode="true" />
[057.593] send ../sdxpoorwills-sysfs.ubi, filesize=64225280
[057.854] Upgrade progress: 62
[058.563] Upgrade progress: 63
[059.274] Upgrade progress: 64
[059.990] Upgrade progress: 65
[060.714] Upgrade progress: 66
[061.435] Upgrade progress: 67
[062.150] Upgrade progress: 68
[062.874] Upgrade progress: 69
[063.602] Upgrade progress: 70
[064.318] Upgrade progress: 71
[065.048] Upgrade progress: 72
[065.777] Upgrade progress: 73
[066.498] Upgrade progress: 74
[067.232] Upgrade progress: 75
[067.964] Upgrade progress: 76
[068.693] Upgrade progress: 77
[069.423] Upgrade progress: 78
[070.161] Upgrade progress: 79
[070.898] Upgrade progress: 80
[071.644] Upgrade progress: 81
[072.378] Upgrade progress: 82
[073.122] Upgrade progress: 83
[073.865] Upgrade progress: 84
[074.597] Upgrade progress: 85
[075.343] Upgrade progress: 86
[076.087] Upgrade progress: 87
[076.828] Upgrade progress: 88
[077.581] Upgrade progress: 89
[078.333] Upgrade progress: 90
[079.080] Upgrade progress: 91
[079.823] Upgrade progress: 92
[080.588] Upgrade progress: 93
[081.340] Upgrade progress: 94
[082.088] Upgrade progress: 95
[082.838] Upgrade progress: 96
[083.597] Upgrade progress: 97
[084.353] Upgrade progress: 98
[085.107] Upgrade progress: 99
[085.613] send finished
[085.713] <response value="ACK" rawmode="false" />
[085.713] <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sbl1.mbn" num_partition_sectors="136" physical_partition_number="0" start_sector="0" />
[085.793] <log value="INFO: Calling handler for program" />
[085.793] <log value="INFO: NAND was previously open, returning existing handle 0." />
[085.793] <response value="ACK" rawmode="true" />
[085.793] send ../sbl1.mbn, filesize=556180
[085.965] Upgrade progress: 100
[085.976] send finished
[086.069] <response value="ACK" rawmode="false" />
[086.069] <power value="reset" />
[086.106] <log value="INFO: Calling handler for power" />
[086.107] <response value="ACK" rawmode="false" />
[086.107] <log value="INFO: Will issue reset/power off 100 useconds, if this hangs check if watchdog is enabled" />
[086.107] <log value="INFO: bsp_target_reset() 1" />
[086.107] qtcp_read read=0, errno: 0 (Success)
[086.107] qusb_noblock_read read=0, errno: 0 (Success)
[086.107] qusb_noblock_read cur=0, min_size=1
[086.107] firehose_protocol.c fh_recv_cmd 294 fail
[086.107] THE TOTAL DOWNLOAD TIME IS 84.093 s
[086.107] Upgrade module successfully.

View File

@ -0,0 +1,60 @@
# ./QFirehose -p /dev/mhi_BHI -f v09
[000.000]: QFirehose Version: Quectel_LTE&5G_QFirehose_Linux&Android_V1.4.5
[000.000]: Builded: Feb 10 2021 14:14:00
[000.000]: Find md5 check file <v09/md5.txt>
[000.000]: Totals checking 0 files md5 value, 0 file fail!
[000.024]: switch_to_edl_mode
[001.027]: poll_wait events=POLLIN msec=1000 timeout
[001.027]: qusb_noblock_read cur=0, min_size=1
[001.027]: switch to 'Emergency download mode'
[001.039]: successful, wait module reboot
[002.040]: bhi_ee = 6
[004.105]: dir=v09/update/firehose
[004.105]: d_name=rawprogram_nand_p4K_b256K_factory.xml
[004.108]: <log value="INFO: Binary build date: Dec 29 2020 @ 09:23:46" />
......
[004.168]: <log value="INFO: End of supported functions 15" />
[005.170]: poll_wait events=POLLIN msec=1000 timeout
[005.170]: qusb_noblock_read cur=0, min_size=1
[005.170]: firehose_protocol.c fh_recv_cmd 327 fail
[005.170]: <configure MemoryName="nand" Verbose="0" AlwaysValidate="0" MaxDigestTableSizeInBytes="2048" MaxPayloadSizeToTargetInBytes="8192" ZlpAwareHost="1" SkipStorageInit="0" />
[005.178]: <log value="INFO: Calling handler for configure" />
[005.181]: <log value="INFO: Storage type set to value nand" />
[005.186]: <response value="ACK" MemoryName="nand" MinVersionSupported="1" Version="1" MaxPayloadSizeToTargetInBytes="8192" MaxPayloadSizeToTargetInBytesSupported="8192" MaxXMLSizeInBytes="4096" DateTime="Dec 29 2020 - 09:23:46" />
[005.186]: <erase PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" num_partition_sectors="512" physical_partition_number="0" start_sector="0" />
[005.193]: <log value="INFO: Calling handler for erase" />
[005.365]: <log value="INFO: [295] bbt_size:100 blocks:800." />
[005.368]: <log value="INFO: [297] bbt_size:100 blocks:800." />
[005.761]: <log value="INFO: Erasing start sector 0, num sectors 0" />
[005.777]: <response value="ACK" rawmode="false" />
......
[011.965]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="partition_complete_p4K_b256K.mbn" num_partition_sectors="4" physical_partition_number="0" start_sector="512" />
[011.972]: <log value="INFO: Calling handler for program" />
[011.976]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[011.979]: <response value="ACK" rawmode="true" />
[011.979]: send partition_complete_p4K_b256K.mbn, filesize=16384
.
[011.979]: upgrade progress 0% 16384/144903062
[011.979]: send finished
[011.997]: <response value="ACK" rawmode="false" />
......
[146.314]: <program PAGES_PER_BLOCK="64" SECTOR_SIZE_IN_BYTES="4096" filename="..\sbl1.mbn" num_partition_sectors="139" physical_partition_number="0" start_sector="0" />
[146.321]: <log value="INFO: Calling handler for program" />
[146.325]: <log value="INFO: NAND was previously open, returning existing handle 0." />
[146.328]: <response value="ACK" rawmode="true" />
[146.328]: send ../sbl1.mbn, filesize=566196
.
[146.616]: upgrade progress 100% 145469258/144903062
[146.616]: send finished
[146.834]: <response value="ACK" rawmode="false" />
[146.834]: <power value="reset" />
[146.840]: <log value="INFO: Calling handler for power" />
[146.843]: <response value="ACK" rawmode="false" />
[146.847]: <log value="INFO: Will issue reset/power off 100 useconds, if this hangs check if watchdog is enabled" />
[146.850]: <log value="INFO: bsp_target_reset() 1" />
[147.852]: poll_wait events=POLLIN msec=1000 timeout
[147.852]: qusb_noblock_read cur=0, min_size=1
[147.852]: firehose_protocol.c fh_recv_cmd 327 fail
[147.852]: THE TOTAL DOWNLOAD TIME IS 143.747 s
[147.852]: Upgrade module successfully.

View File

@ -0,0 +1,477 @@
/*
Copyright 2023 Quectel Wireless Solutions Co.,Ltd
Quectel hereby grants customers of Quectel a license to use, modify,
distribute and publish the Software in binary form provided that
customers shall have no right to reverse engineer, reverse assemble,
decompile or reduce to source code form any portion of the Software.
Under no circumstances may customers modify, demonstrate, use, deliver
or disclose any portion of the Software in source code form.
*/
#include "md5.h"
#include <endian.h> //for __BYTE_ORDER
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
#define H(x, y, z) (((x) ^ (y)) ^ (z))
#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
#define I(x, y, z) ((y) ^ ((x) | ~(z)))
#define STEP(f, a, b, c, d, x, t, s) \
(a) += f((b), (c), (d)) + (x) + (t); \
(a) = (((a) << (s)) | (((a)&0xffffffff) >> (32 - (s)))); \
(a) += (b);
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define SET(n) (*(uint32_t *)&ptr[(n)*4])
#define GET(n) SET(n)
#else
#define SET(n) \
(block[(n)] = (uint32_t)ptr[(n)*4] | ((uint32_t)ptr[(n)*4 + 1] << 8) | \
((uint32_t)ptr[(n)*4 + 2] << 16) | ((uint32_t)ptr[(n)*4 + 3] << 24))
#define GET(n) (block[(n)])
#endif
extern char firehose_unzip_full_dir[256];
extern char firehose_zip_name[80];
static const void *body(md5_ctx_t *ctx, const void *data, unsigned long size)
{
const unsigned char *ptr;
uint32_t a, b, c, d;
uint32_t saved_a, saved_b, saved_c, saved_d;
#if __BYTE_ORDER != __LITTLE_ENDIAN
uint32_t block[16];
#endif
ptr = (const unsigned char *)data;
a = ctx->a;
b = ctx->b;
c = ctx->c;
d = ctx->d;
do
{
saved_a = a;
saved_b = b;
saved_c = c;
saved_d = d;
/* Round 1 */
STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
/* Round 2 */
STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
/* Round 3 */
STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
/* Round 4 */
STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
a += saved_a;
b += saved_b;
c += saved_c;
d += saved_d;
ptr += 64;
} while (size -= 64);
ctx->a = a;
ctx->b = b;
ctx->c = c;
ctx->d = d;
return ptr;
}
void md5_begin(md5_ctx_t *ctx)
{
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
ctx->c = 0x98badcfe;
ctx->d = 0x10325476;
ctx->lo = 0;
ctx->hi = 0;
}
void md5_hash(const void *data, size_t size, md5_ctx_t *ctx)
{
uint32_t saved_lo;
unsigned long used, available;
saved_lo = ctx->lo;
if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) ctx->hi++;
ctx->hi += size >> 29;
used = saved_lo & 0x3f;
if (used)
{
available = 64 - used;
if (size < available)
{
memcpy(&ctx->buffer[used], data, size);
return;
}
memcpy(&ctx->buffer[used], data, available);
data = (const unsigned char *)data + available;
size -= available;
body(ctx, ctx->buffer, 64);
}
if (size >= 64)
{
data = body(ctx, data, size & ~((size_t)0x3f));
size &= 0x3f;
}
memcpy(ctx->buffer, data, size);
}
void md5_end(void *resbuf, md5_ctx_t *ctx)
{
unsigned char *result = (unsigned char *)resbuf;
unsigned long used, available;
used = ctx->lo & 0x3f;
ctx->buffer[used++] = 0x80;
available = 64 - used;
if (available < 8)
{
memset(&ctx->buffer[used], 0, available);
body(ctx, ctx->buffer, 64);
used = 0;
available = 64;
}
if (used >= 64) return (void)0;
memset(&ctx->buffer[used], 0, available - 8);
ctx->lo <<= 3;
ctx->buffer[56] = ctx->lo;
ctx->buffer[57] = ctx->lo >> 8;
ctx->buffer[58] = ctx->lo >> 16;
ctx->buffer[59] = ctx->lo >> 24;
ctx->buffer[60] = ctx->hi;
ctx->buffer[61] = ctx->hi >> 8;
ctx->buffer[62] = ctx->hi >> 16;
ctx->buffer[63] = ctx->hi >> 24;
body(ctx, ctx->buffer, 64);
result[0] = ctx->a;
result[1] = ctx->a >> 8;
result[2] = ctx->a >> 16;
result[3] = ctx->a >> 24;
result[4] = ctx->b;
result[5] = ctx->b >> 8;
result[6] = ctx->b >> 16;
result[7] = ctx->b >> 24;
result[8] = ctx->c;
result[9] = ctx->c >> 8;
result[10] = ctx->c >> 16;
result[11] = ctx->c >> 24;
result[12] = ctx->d;
result[13] = ctx->d >> 8;
result[14] = ctx->d >> 16;
result[15] = ctx->d >> 24;
memset(ctx, 0, sizeof(*ctx));
}
int md5sum(char *file, void *md5_buf)
{
char buf[256];
md5_ctx_t ctx;
int ret = 0;
FILE *f;
f = fopen(file, "r");
if (!f) return -1;
md5_begin(&ctx);
do
{
int len = fread(buf, 1, sizeof(buf), f);
if (!len) break;
md5_hash(buf, len, &ctx);
ret += len;
} while (1);
md5_end(md5_buf, &ctx);
fclose(f);
return ret;
}
int md5_check(const char *firehose_dir)
{
FILE *fp = NULL;
char md5_file_path[256], buff[256], file_name[128], file_name_tmp[128], file_full_path[256],
file_md5_value[64];
char *ps = NULL, *pe = NULL;
unsigned char compute_md5_buff[16];
char convert_md5_buff[33];
int i, file_count = 0, fail_count = 0;
if (is_upgrade_fimeware_zip_7z)
{
memset(zip_cmd_buf, 0, sizeof(zip_cmd_buf));
if (is_upgrade_fimeware_only_zip)
{
if (is_firehose_zip_7z_name_exit)
{
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf),
"unzip -o -q %.240s %.76s/'*md5.txt' -d /tmp/ > %s", firehose_dir,
firehose_zip_name, ZIP_PROCESS_INFO);
}
else
{
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf),
"unzip -o -q %.240s '*md5.txt' -d /tmp/ > %s", firehose_dir,
ZIP_PROCESS_INFO);
}
}
else
{
if (is_firehose_zip_7z_name_exit)
{
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf), "7z x %.240s -o/tmp/ %.76s/md5.txt > %s",
firehose_dir, firehose_zip_name, ZIP_PROCESS_INFO);
}
else
{
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf), "7z x %.240s -o/tmp/ md5.txt > %s",
firehose_dir, ZIP_PROCESS_INFO);
}
}
printf("%s zip_cmd_buf:%s\n", __func__, zip_cmd_buf);
if (-1 == system(zip_cmd_buf))
{
printf("%s system return error\n", __func__);
return -1;
}
usleep(1000);
snprintf(md5_file_path, sizeof(md5_file_path), "%.240s/md5.txt", firehose_unzip_full_dir);
if (access(md5_file_path, R_OK))
{
dbg_time("Cann't find md5.txt in %s, Please check it!\n", md5_file_path);
return -1;
}
else
{
dbg_time("Find md5 check file <%s>\n", md5_file_path);
}
}
else
{
snprintf(md5_file_path, sizeof(md5_file_path), "%.240s/md5.txt", firehose_dir);
if (access(md5_file_path, R_OK))
{
dbg_time("Cann't find md5.txt in %s, Please check it!\n", firehose_dir);
return 0; // allow skip md5 check by delete md5.txt
}
else
{
dbg_time("Find md5 check file <%s>\n", md5_file_path);
}
}
fp = fopen(md5_file_path, "rb");
if (fp == NULL)
{
dbg_time("fail to fopen(%s), error: %d (%s)\n", md5_file_path, errno, strerror(errno));
return -1;
}
while (fgets(buff, sizeof(buff), fp))
{
if (strstr(buff, "targetfiles.zip")) continue;
ps = strstr(buff, ":\\");
if (ps == NULL) continue;
file_count++;
ps = ps + 1;
pe = strstr(ps, ":");
if (pe == NULL) continue;
memcpy(file_name, ps, pe - ps);
file_name[pe - ps] = '\0';
for (i = 0; file_name[i] != '\0'; i++)
{
if (file_name[i] == '\\') file_name[i] = '/';
}
memcpy(file_md5_value, pe + 1, 32);
file_md5_value[32] = '\0';
if (is_upgrade_fimeware_zip_7z)
{
char *p1 = strchr(file_name, '/');
memset(file_name_tmp, 0, sizeof(file_name_tmp));
strncpy(file_name_tmp, p1 + 1, strlen(p1) - 1);
memset(zip_cmd_buf, 0, sizeof(zip_cmd_buf));
if (is_upgrade_fimeware_only_zip)
{
if (is_firehose_zip_7z_name_exit)
{
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf),
"unzip -o -q %.240s %.76s/'*%.120s' -d /tmp/ > %s", firehose_dir,
firehose_zip_name, file_name_tmp, ZIP_PROCESS_INFO);
}
else
{
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf),
"unzip -o -q %.240s '*%.120s' -d /tmp/ > %s", firehose_dir,
file_name_tmp, ZIP_PROCESS_INFO);
}
}
else
{
if (is_firehose_zip_7z_name_exit)
{
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf),
"7z x %.240s -o/tmp/ %.76s/%.120s > %s", firehose_dir,
firehose_zip_name, file_name_tmp, ZIP_PROCESS_INFO);
}
else
{
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf), "7z x %.240s -o/tmp/ %.120s > %s",
firehose_dir, file_name_tmp, ZIP_PROCESS_INFO);
}
}
dbg_time("%s zip_cmd_buf:%s\n", __func__, zip_cmd_buf);
if (-1 == system(zip_cmd_buf))
{
dbg_time("%s system return error\n", __func__);
return -1;
}
usleep(1000);
snprintf(file_full_path, sizeof(file_full_path), "%.160s%.80s", firehose_unzip_full_dir,
file_name);
dbg_time("%s file_full_path:%s\n", __func__, file_full_path);
}
else
{
snprintf(file_full_path, sizeof(file_full_path), "%.160s%.80s", firehose_dir,
file_name);
}
if (access(file_full_path, R_OK))
{
continue;
}
md5sum(file_full_path, compute_md5_buff);
for (i = 0; i < 16; i++)
{
sprintf(convert_md5_buff + (i * 2), "%02X", compute_md5_buff[i]);
}
if (strncasecmp(file_md5_value, convert_md5_buff, 16))
{
fail_count++;
dbg_time("md5 checking: %s fail\n", file_full_path);
dbg_time("find %s, should be %s\n", file_md5_value, convert_md5_buff);
}
else
{
dbg_time("md5 checking: %s pass\n", file_full_path);
}
if (is_upgrade_fimeware_zip_7z)
{
dbg_time("%s delet %s ...\n", __func__, file_full_path);
unlink(file_full_path); // delete all file
}
}
fclose(fp);
if (is_upgrade_fimeware_zip_7z)
{
unlink(md5_file_path); // delete md5.txt
}
dbg_time("Totals checking %d files md5 value, %d file fail!\n", file_count, fail_count);
return (fail_count ? -1 : 0);
}

View File

@ -0,0 +1,33 @@
/*
Copyright 2023 Quectel Wireless Solutions Co.,Ltd
Quectel hereby grants customers of Quectel a license to use, modify,
distribute and publish the Software in binary form provided that
customers shall have no right to reverse engineer, reverse assemble,
decompile or reduce to source code form any portion of the Software.
Under no circumstances may customers modify, demonstrate, use, deliver
or disclose any portion of the Software in source code form.
*/
#ifndef _QUECTEL_MD5_H
#define _QUECTEL_MD5_H
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <stddef.h>
#include <unistd.h>
#include "usb_linux.h"
typedef struct md5_ctx
{
uint32_t lo, hi;
uint32_t a, b, c, d;
unsigned char buffer[64];
} md5_ctx_t;
// void dbg_time (const char *fmt, ...);
extern int md5_check(const char *);
#endif /* _QUECTEL_MD5_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,529 @@
/*
Copyright 2023 Quectel Wireless Solutions Co.,Ltd
Quectel hereby grants customers of Quectel a license to use, modify,
distribute and publish the Software in binary form provided that
customers shall have no right to reverse engineer, reverse assemble,
decompile or reduce to source code form any portion of the Software.
Under no circumstances may customers modify, demonstrate, use, deliver
or disclose any portion of the Software in source code form.
*/
#include "usb_linux.h"
#include "sahara.h"
static uint32_t le_uint32(uint32_t v32)
{
const int is_bigendian = 1;
uint32_t tmp = v32;
if ((*(char *)&is_bigendian) == 0)
{
unsigned char *s = (unsigned char *)(&v32);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
d[3] = s[0];
}
return tmp;
}
static uint64_t le_uint64(uint64_t v64)
{
const int is_bigendian = 1;
uint64_t tmp = v64;
if ((*(char *)&is_bigendian) == 0)
{
unsigned char *s = (unsigned char *)(&v64);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[7];
d[1] = s[6];
d[2] = s[5];
d[3] = s[4];
d[4] = s[3];
d[5] = s[2];
d[6] = s[1];
d[7] = s[0];
}
return tmp;
}
#define dbg(log_level, fmt, arg...) \
do \
{ \
dbg_time(fmt "\n", ##arg); \
} while (0)
static int sahara_tx_data(void *usb_handle, void *tx_buffer, size_t bytes_to_send)
{
int need_zlp = 0; // zlp is not mandatory
return qusb_noblock_write(usb_handle, tx_buffer, bytes_to_send, bytes_to_send, 3000, need_zlp);
}
int qusb_use_usbfs_interface(const void *handle);
static int sahara_rx_data(void *usb_handle, void *rx_buffer, size_t bytes_to_read)
{
q_sahara_packet_h *command_packet_header = NULL;
size_t bytes_read = 0;
const char *q_sahara_cmd_str[Q_SAHARA_NINETEEN] = {
"Q_SAHARA_ZERO", // = 0x00,
"Q_SAHARA_ONE", // = 0x01, // sent from target to host
"Q_SAHARA_TWO", // = 0x02, // sent from host to target
"Q_SAHARA_THREE", // = 0x03, // sent from target to host
"Q_SAHARA_FOUR", // = 0x04, // sent from target to host
"Q_SAHARA_FIVE", // = 0x05, // sent from host to target
"Q_SAHARA_SIX", // = 0x06, // sent from target to host
"Q_SAHARA_SEVEN", // = 0x07, // sent from host to target
"Q_SAHARA_EIGTH", // = 0x08, // sent from target to host
"Q_SAHARA_NINE", // = 0x09, // sent from target to host
"Q_SAHARA_TEN", // = 0x0A, // sent from host to target
"Q_SAHARA_ELEVEN", // = 0x0B, // sent from target to host
"Q_SAHARA_TWELEVE", // = 0x0C, // sent from host to target
"Q_SAHARA_THIRTEEN", // = 0x0D, // sent from host to target
"Q_SAHARA_FOURTEEN", // = 0x0E, // sent from target to host
"Q_SAHARA_FIFTEEN", // = 0x0F, // sent from host to target
"Q_SAHARA_SIXTEEN", // = 0x10, // sent from target to host
"Q_SAHARA_SEVENTEEN", // = 0x11, // sent from host to target
"Q_SAHARA_EIGHTEEN", // = 0x12,
};
if (0 == bytes_to_read)
{
if (qusb_use_usbfs_interface(usb_handle))
{
bytes_read = qusb_noblock_read(usb_handle, rx_buffer, Q_SAHARA_RAW_BUF_SZ, 0, 5000);
if (bytes_read < sizeof(q_sahara_packet_h)) return 0;
}
else
{
bytes_read =
qusb_noblock_read(usb_handle, rx_buffer, sizeof(q_sahara_packet_h), 0, 5000);
if (bytes_read != sizeof(q_sahara_packet_h)) return 0;
}
command_packet_header = (q_sahara_packet_h *)rx_buffer;
if (le_uint32(command_packet_header->q_cmd) < Q_SAHARA_NINETEEN)
{
dbg(LOG_EVENT, "<=== %s", q_sahara_cmd_str[le_uint32(command_packet_header->q_cmd)]);
if (!qusb_use_usbfs_interface(usb_handle))
{
bytes_read += qusb_noblock_read(
usb_handle, (uint8_t *)rx_buffer + sizeof(q_sahara_packet_h),
le_uint32(command_packet_header->q_len) - sizeof(q_sahara_packet_h), 0, 5000);
}
if (bytes_read != (le_uint32(command_packet_header->q_len)))
{
dbg(LOG_INFO, "Read %zd bytes, Header indicates q_cmd %d and packet q_len %d bytes",
bytes_read, le_uint32(command_packet_header->q_cmd),
le_uint32(command_packet_header->q_len));
return 0;
}
}
else
{
dbg(LOG_EVENT, "<=== SAHARA_CMD_UNKONOW_%d", le_uint32(command_packet_header->q_cmd));
return 0;
}
}
else
{
bytes_read = qusb_noblock_read(usb_handle, rx_buffer, bytes_to_read, bytes_to_read, 5000);
}
return 1;
}
static int send_reset_command(void *usb_handle, void *tx_buffer)
{
struct sahara_pkt *sahara_reset;
sahara_reset = (struct sahara_pkt *)tx_buffer;
sahara_reset->q_header.q_cmd = le_uint32(Q_SAHARA_SEVEN);
sahara_reset->q_header.q_len =
le_uint32(sizeof(sahara_reset->q_sahara_reset_packet) + sizeof(q_sahara_packet_h));
/* Send the Reset Request */
dbg(LOG_EVENT, "SAHARA_RESET ===>");
if (0 ==
sahara_tx_data(usb_handle, tx_buffer,
sizeof(sahara_reset->q_sahara_reset_packet) + sizeof(q_sahara_packet_h)))
{
dbg(LOG_ERROR, "Sending RESET packet failed");
return 0;
}
return 1;
}
static int send_done_packet(void *usb_handle, void *tx_buffer)
{
struct sahara_pkt *sahara_done;
sahara_done = (struct sahara_pkt *)tx_buffer;
sahara_done->q_header.q_cmd = le_uint32(Q_SAHARA_FIVE);
sahara_done->q_header.q_len =
le_uint32(sizeof(sahara_done->q_sahara_done_packet) + sizeof(q_sahara_packet_h));
// Send the image data
dbg(LOG_EVENT, "Q_SAHARA_FIVE ===>");
if (0 == sahara_tx_data(usb_handle, tx_buffer,
sizeof(sahara_done->q_sahara_done_packet) + sizeof(q_sahara_packet_h)))
{
dbg(LOG_ERROR, "Sending DONE packet failed");
return 0;
}
return 1;
}
static int start_image_transfer(void *usb_handle, void *tx_buffer,
const struct sahara_pkt *pr_sahara_pkt, FILE *file_handle)
{
int retval = 0;
uint32_t bytes_read = 0, bytes_to_read_next;
uint32_t q_image_id = le_uint32(pr_sahara_pkt->q_sahara_read_packet_data.q_image_id);
uint32_t DataOffset = le_uint32(pr_sahara_pkt->q_sahara_read_packet_data.q_data_offset);
uint32_t DataLength = le_uint32(pr_sahara_pkt->q_sahara_read_packet_data.q_data_length);
if (le_uint32(pr_sahara_pkt->q_header.q_cmd) == Q_SAHARA_EIGHTEEN)
{
q_image_id = le_uint64(pr_sahara_pkt->q_sahara_read_packet_data_64bit.q_image_id);
DataOffset = le_uint64(pr_sahara_pkt->q_sahara_read_packet_data_64bit.q_data_offset);
DataLength = le_uint64(pr_sahara_pkt->q_sahara_read_packet_data_64bit.q_data_length);
}
dbg(LOG_INFO, "0x%08x 0x%08x 0x%08x", q_image_id, DataOffset, DataLength);
if (fseek(file_handle, (long)DataOffset, SEEK_SET))
{
dbg(LOG_INFO, "%d errno: %d (%s)", __LINE__, errno, strerror(errno));
return 0;
}
while (bytes_read < DataLength)
{
bytes_to_read_next = MIN((uint32_t)DataLength - bytes_read, Q_SAHARA_RAW_BUF_SZ);
retval = fread(tx_buffer, 1, bytes_to_read_next, file_handle);
if (retval < 0)
{
dbg(LOG_ERROR, "file read failed: %s", strerror(errno));
return 0;
}
if ((uint32_t)retval != bytes_to_read_next)
{
dbg(LOG_ERROR, "Read %d bytes, but was asked for 0x%08x bytes", retval, DataLength);
return 0;
}
/*send the image data*/
if (0 == sahara_tx_data(usb_handle, tx_buffer, bytes_to_read_next))
{
dbg(LOG_ERROR, "Tx Sahara Image Failed");
return 0;
}
bytes_read += bytes_to_read_next;
}
return 1;
}
static int send_hello_response(void *usb_handle, void *tx_buffer,
const struct sahara_pkt *sahara_hello)
{
struct sahara_pkt *sahara_hello_resp;
sahara_hello_resp = (struct sahara_pkt *)tx_buffer;
// Recieved hello, send the hello response
// Create a Hello request
sahara_hello_resp->q_header.q_cmd = le_uint32(Q_SAHARA_TWO);
sahara_hello_resp->q_header.q_len = le_uint32(
sizeof(sahara_hello_resp->q_sahara_hello_packet_response) + sizeof(q_sahara_packet_h));
sahara_hello_resp->q_sahara_hello_packet_response.q_ver =
sahara_hello->q_sahara_hello_packet.q_ver;
sahara_hello_resp->q_sahara_hello_packet_response.q_ver_sup =
sahara_hello->q_sahara_hello_packet.q_ver_sup;
sahara_hello_resp->q_sahara_hello_packet_response.q_status = le_uint32(Q_SAHARA_STATUS_ZERO);
sahara_hello_resp->q_sahara_hello_packet_response.q_mode =
sahara_hello->q_sahara_hello_packet.q_mode;
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve1 = le_uint32(1);
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve2 = le_uint32(2);
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve3 = le_uint32(3);
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve4 = le_uint32(4);
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve5 = le_uint32(5);
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve6 = le_uint32(6);
if (le_uint32(sahara_hello->q_sahara_hello_packet.q_mode) != Q_SAHARA_MODE_ZERO)
{
dbg(LOG_ERROR, "ERROR NOT Q_SAHARA_MODE_ZERO");
sahara_hello_resp->q_sahara_hello_packet_response.q_mode = Q_SAHARA_MODE_ZERO;
}
/*Send the Hello Resonse Request*/
dbg(LOG_EVENT, "Q_SAHARA_TWO ===>");
if (0 == sahara_tx_data(usb_handle, tx_buffer,
sizeof(sahara_hello_resp->q_sahara_hello_packet_response) +
sizeof(q_sahara_packet_h)))
{
dbg(LOG_ERROR, "Tx Sahara Data Failed ");
return 0;
}
return 1;
}
static int sahara_flash_all(void *usb_handle, void *tx_buffer, void *rx_buffer, FILE *file_handle)
{
uint32_t q_image_id = 0;
struct sahara_pkt *pr_sahara_pkt;
pr_sahara_pkt = (struct sahara_pkt *)rx_buffer;
if (0 == sahara_rx_data(usb_handle, rx_buffer, 0))
{
sahara_tx_data(usb_handle, tx_buffer, 1);
if (0 == sahara_rx_data(usb_handle, rx_buffer, 0)) return 0;
}
if (le_uint32(pr_sahara_pkt->q_header.q_cmd) != Q_SAHARA_ONE)
{
dbg(LOG_ERROR, "Received a different q_cmd: %x while waiting for hello packet",
pr_sahara_pkt->q_header.q_cmd);
send_reset_command(usb_handle, rx_buffer);
return 0;
}
if (0 == send_hello_response(usb_handle, tx_buffer, pr_sahara_pkt))
{
dbg(LOG_ERROR, "send_hello_response failed\n");
return 0;
}
while (1)
{
if (0 == sahara_rx_data(usb_handle, rx_buffer, 0)) return 0;
if (le_uint32(pr_sahara_pkt->q_header.q_cmd) == Q_SAHARA_THREE)
{
start_image_transfer(usb_handle, tx_buffer, pr_sahara_pkt, file_handle);
}
else if (le_uint32(pr_sahara_pkt->q_header.q_cmd) == Q_SAHARA_EIGHTEEN)
{
start_image_transfer(usb_handle, tx_buffer, pr_sahara_pkt, file_handle);
}
else if (le_uint32(pr_sahara_pkt->q_header.q_cmd) == Q_SAHARA_FOUR)
{
dbg(LOG_EVENT, "q_image_id = %d, q_status = %d",
le_uint32(pr_sahara_pkt->q_sahara_end_packet_image_tx.q_image_id),
le_uint32(pr_sahara_pkt->q_sahara_end_packet_image_tx.q_status));
if (le_uint32(pr_sahara_pkt->q_sahara_end_packet_image_tx.q_status) ==
Q_SAHARA_STATUS_ZERO)
{
q_image_id = le_uint32(pr_sahara_pkt->q_sahara_end_packet_image_tx.q_image_id);
send_done_packet(usb_handle, tx_buffer);
break;
}
else
{
return 0;
}
}
else if (le_uint32(pr_sahara_pkt->q_header.q_cmd) == Q_SAHARA_ONE)
{
continue;
}
else
{
dbg(LOG_ERROR, "Received an unknown q_cmd: %d ",
le_uint32(pr_sahara_pkt->q_header.q_cmd));
send_reset_command(usb_handle, tx_buffer);
return 0;
}
}
if (0 == sahara_rx_data(usb_handle, rx_buffer, 0)) return 0;
dbg(LOG_INFO, "q_image_tx_status = %d",
le_uint32(pr_sahara_pkt->q_sahara_done_packet_response.q_image_tx_status));
if (Q_SAHARA_MODE_ZERO ==
le_uint32(pr_sahara_pkt->q_sahara_done_packet_response.q_image_tx_status))
{
if (q_image_id == 13) // prog_nand_firehose_9x07.mbn
return 1;
if (q_image_id == 7) // NPRG9x55.mbn
return 1;
if (q_image_id == 21) // sbl1.mbn, October 22 2020 2:12 PM, AG35CEVAR05A07T4G
return 1;
}
else if (Q_SAHARA_MODE_ONE ==
le_uint32(pr_sahara_pkt->q_sahara_done_packet_response.q_image_tx_status))
{
dbg(LOG_EVENT, "Successfully flash all images");
return 1;
}
else
{
dbg(LOG_ERROR, "Received unrecognized q_status %d at Q_SAHARA_WAIT_FOUR state",
le_uint32(pr_sahara_pkt->q_sahara_done_packet_response.q_image_tx_status));
return 0;
}
return 0;
}
int sahara_main(const char *firehose_dir, const char *firehose_mbn, void *usb_handle,
int edl_mode_05c69008)
{
int retval = 0;
char full_path[512];
FILE *file_handle;
void *tx_buffer;
void *rx_buffer;
if (edl_mode_05c69008)
{
if (is_upgrade_fimeware_zip_7z)
{
snprintf(full_path, sizeof(full_path), "/tmp/%.240s", firehose_mbn);
dbg_time("%s full_path:%s\n", __func__, full_path);
}
else
{
snprintf(full_path, sizeof(full_path), "%.255s/%.240s", firehose_dir, firehose_mbn);
}
}
else
{
char *prog_nand_firehose_filename = NULL;
if (is_upgrade_fimeware_zip_7z)
{
int i;
char prog_nand_firehose_filename_tmp[128] = {0};
char prog_nand_firehose_filename_dir_tmp[256] = {0};
prog_nand_firehose_filename = (char *)malloc(256);
if (prog_nand_firehose_filename == NULL)
{
return ENOENT;
}
for (i = 0; i < file_name_b.file_name_count; i++)
{
if ((strstr(file_name_b.file_backup_c[i].zip_file_name_backup, "NPRG9x") &&
strstr(file_name_b.file_backup_c[i].zip_file_name_backup, ".mbn")))
{
dbg_time("file_name_b.file_backup_c[i].zip_file_name_backup:%s\n",
file_name_b.file_backup_c[i].zip_file_name_backup);
dbg_time("file_name_b.file_backup_c[i].zip_file_dir_backup:%s\n",
file_name_b.file_backup_c[i].zip_file_dir_backup);
if (strstr(file_name_b.file_backup_c[i].zip_file_dir_backup, "update/firehose"))
{
memmove(prog_nand_firehose_filename_tmp,
file_name_b.file_backup_c[i].zip_file_name_backup,
strlen(file_name_b.file_backup_c[i].zip_file_name_backup));
memmove(prog_nand_firehose_filename_dir_tmp,
file_name_b.file_backup_c[i].zip_file_dir_backup,
strlen(file_name_b.file_backup_c[i].zip_file_dir_backup));
break;
}
}
}
if (prog_nand_firehose_filename_tmp[0] != '\0')
{
memset(zip_cmd_buf, 0, sizeof(zip_cmd_buf));
if (is_upgrade_fimeware_only_zip)
{
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf),
"unzip -o -q %.240s '*%.200s' -d /tmp/ > %s", firehose_dir,
prog_nand_firehose_filename_dir_tmp, ZIP_PROCESS_INFO);
}
else
{
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf), "7z x %.240s -o/tmp/ %.200s > %s",
firehose_dir, prog_nand_firehose_filename_dir_tmp, ZIP_PROCESS_INFO);
}
dbg_time("%s zip_cmd_buf:%s\n", __func__, zip_cmd_buf);
if (-1 == system(zip_cmd_buf))
{
dbg_time("%s system return error\n", __func__);
safe_free(prog_nand_firehose_filename);
return ENOENT;
}
usleep(1000);
memmove(prog_nand_firehose_filename, prog_nand_firehose_filename_dir_tmp, 240);
dbg(LOG_INFO, "prog_nand_firehose_filename = %s", prog_nand_firehose_filename);
snprintf(full_path, sizeof(full_path), "/tmp/%.240s", prog_nand_firehose_filename);
}
}
else
{
snprintf(full_path, sizeof(full_path), "%.255s/..", firehose_dir);
if (!qfile_find_file(full_path, "NPRG9x", ".mbn", &prog_nand_firehose_filename) &&
!qfile_find_file(full_path, "NPRG9x", ".mbn", &prog_nand_firehose_filename))
{
dbg(LOG_ERROR, "retrieve NPRG MBN failed.");
safe_free(prog_nand_firehose_filename);
return ENOENT;
}
dbg(LOG_INFO, "prog_nand_firehose_filename = %s", prog_nand_firehose_filename);
snprintf(full_path, sizeof(full_path), "%.255s/../%.240s", firehose_dir,
prog_nand_firehose_filename);
}
safe_free(prog_nand_firehose_filename);
}
file_handle = fopen(full_path, "rb");
if (file_handle == NULL)
{
dbg(LOG_INFO, "%s %d %s errno: %d (%s)", __func__, __LINE__, full_path, errno,
strerror(errno));
return ENOENT;
}
rx_buffer = malloc(Q_SAHARA_RAW_BUF_SZ);
tx_buffer = malloc(Q_SAHARA_RAW_BUF_SZ);
if (NULL == rx_buffer || NULL == tx_buffer)
{
dbg(LOG_ERROR, "Failed to allocate sahara buffers");
safe_free(rx_buffer);
safe_free(tx_buffer);
fclose(file_handle);
file_handle = NULL;
return ENOMEM;
}
retval = sahara_flash_all(usb_handle, tx_buffer, rx_buffer, file_handle);
if (0 == retval)
{
dbg(LOG_ERROR, "Sahara protocol error");
}
else
{
dbg(LOG_STATUS, "Sahara protocol completed");
}
safe_free(rx_buffer);
safe_free(tx_buffer);
fclose(file_handle);
file_handle = NULL;
if (is_upgrade_fimeware_zip_7z)
{
unlink(full_path);
}
if (retval) return 0;
return __LINE__;
}

View File

@ -0,0 +1,94 @@
/*
Copyright 2023 Quectel Wireless Solutions Co.,Ltd
Quectel hereby grants customers of Quectel a license to use, modify,
distribute and publish the Software in binary form provided that
customers shall have no right to reverse engineer, reverse assemble,
decompile or reduce to source code form any portion of the Software.
Under no circumstances may customers modify, demonstrate, use, deliver
or disclose any portion of the Software in source code form.
*/
#ifndef SAHARA_H
#define SAHARA_H
#define Q_SAHARA_RAW_BUF_SZ (4*1024)
#define Q_SAHARA_STATUS_ZERO 0x00
#define Q_SAHARA_MODE_ZERO 0x00
#define Q_SAHARA_MODE_ONE 0x01
#define Q_SAHARA_ZERO 0x00
#define Q_SAHARA_ONE 0x01
#define Q_SAHARA_TWO 0x02
#define Q_SAHARA_THREE 0x03
#define Q_SAHARA_FOUR 0x04
#define Q_SAHARA_FIVE 0x05
#define Q_SAHARA_SEVEN 0x07
#define Q_SAHARA_EIGHTEEN 0x12
#define Q_SAHARA_NINETEEN 0x13
typedef struct
{
uint32_t q_cmd;
uint32_t q_len;
} q_sahara_packet_h;
struct sahara_pkt
{
q_sahara_packet_h q_header;
union
{
struct
{
uint32_t q_ver;
uint32_t q_ver_sup;
uint32_t q_cmd_packet_len;
uint32_t q_mode;
} q_sahara_hello_packet;
struct
{
uint32_t q_ver;
uint32_t q_ver_sup;
uint32_t q_status;
uint32_t q_mode;
uint32_t q_reserve1;
uint32_t q_reserve2;
uint32_t q_reserve3;
uint32_t q_reserve4;
uint32_t q_reserve5;
uint32_t q_reserve6;
} q_sahara_hello_packet_response;
struct
{
uint32_t q_image_id;
uint32_t q_data_offset;
uint32_t q_data_length;
} q_sahara_read_packet_data;
struct
{
uint32_t q_image_id;
uint32_t q_status;
} q_sahara_end_packet_image_tx;
struct
{
} q_sahara_done_packet;
struct
{
uint32_t q_image_tx_status;
} q_sahara_done_packet_response;
struct
{
uint64_t q_image_id;
uint64_t q_data_offset;
uint64_t q_data_length;
} q_sahara_read_packet_data_64bit;
struct
{
} q_sahara_reset_packet;
struct
{
} q_sahara_reset_packet_response;
};
};
#endif

View File

@ -0,0 +1,826 @@
/*
Copyright 2023 Quectel Wireless Solutions Co.,Ltd
Quectel hereby grants customers of Quectel a license to use, modify,
distribute and publish the Software in binary form provided that
customers shall have no right to reverse engineer, reverse assemble,
decompile or reduce to source code form any portion of the Software.
Under no circumstances may customers modify, demonstrate, use, deliver
or disclose any portion of the Software in source code form.
*/
#include "usb_linux.h"
#include "hostdl_packet.h"
#define true (1 == 1)
#define false (1 != 1)
#define MAX_SEND_BUFFER_SIZE 1280
#define MAX_RECEIVE_BUFFER_SIZE 1280
unsigned char g_Transmit_Buffer[MAX_SEND_BUFFER_SIZE];
int g_Transmit_Length;
unsigned char g_Receive_Buffer[MAX_RECEIVE_BUFFER_SIZE];
int g_Receive_Bytes;
static void *stream_usb_handle;
static void dump_buffer(unsigned char *buff, int len)
{
int i = 0;
dbg_time("dump buffer: %d bytes\n", len);
for (i = 0; i < len; i++)
{
dbg_time("%02x ", buff[i]);
}
dbg_time("\nend\n");
}
#define CRC_16_L_SEED 0xFFFF
#define CRC_TAB_SIZE 256 /* 2^CRC_TAB_BITS */
#define CRC_16_L_POLYNOMIAL 0x8408
static const uint16_t crc_16_l_table[CRC_TAB_SIZE] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3,
0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399,
0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 0xac42, 0x9ed9, 0x8f50,
0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 0x430c, 0x7197, 0x601e,
0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 0xfec7, 0xcc5c, 0xddd5,
0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 0x9581, 0xa71a, 0xb693,
0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 0x0948, 0x3bd3, 0x2a5a,
0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 0xa402, 0x9699, 0x8710,
0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 0x5bcd, 0x6956, 0x78df,
0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 0xf687, 0xc41c, 0xd595,
0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 0x6a4e, 0x58d5, 0x495c,
0x3de3, 0x2c6a, 0x1ef1, 0x0f78};
unsigned short crc_16_l_calc(unsigned char *buf_ptr, int len)
{
int data, crc_16;
for (crc_16 = CRC_16_L_SEED; len >= 8; len -= 8, buf_ptr++)
{
crc_16 = crc_16_l_table[(crc_16 ^ *buf_ptr) & 0x00ff] ^ (crc_16 >> 8);
}
if (len != 0)
{
data = ((int)(*buf_ptr)) << (16 - 8);
while (len-- != 0)
{
if (((crc_16 ^ data) & 0x01) != 0)
{
crc_16 >>= 1;
crc_16 ^= CRC_16_L_POLYNOMIAL;
}
else
{
crc_16 >>= 1;
}
data >>= 1;
}
}
return (~crc_16);
}
void compute_reply_crc()
{
unsigned short crc = crc_16_l_calc(g_Transmit_Buffer, g_Transmit_Length * 8);
g_Transmit_Buffer[g_Transmit_Length] = crc & 0xFF;
g_Transmit_Buffer[g_Transmit_Length + 1] = crc >> 8;
g_Transmit_Length += 2;
}
static void compose_packet(unsigned char cmd, unsigned char *parameter, uint32_t parameter_len,
unsigned char *data, uint32_t data_len)
{
uint32_t i;
g_Transmit_Buffer[0] = cmd;
if (parameter == NULL) parameter_len = 0;
if (data == NULL) data_len = 0;
for (i = 0; i < parameter_len; i++)
{
g_Transmit_Buffer[1 + i] = parameter[i];
}
for (i = 0; i < data_len; i++)
{
g_Transmit_Buffer[1 + parameter_len + i] = data[i];
}
g_Transmit_Length = 1 + parameter_len + data_len;
g_Transmit_Buffer[g_Transmit_Length] = 0;
}
static unsigned char stream_tx_buf[1280];
#define CHECK_FOR_DATA() \
do \
{ \
} while (0)
#define TRANSMIT_BYTE(_byte) \
do \
{ \
stream_tx_buf[j++] = _byte; \
} while (0)
static int send_packet(int flag)
{
int i;
int ch;
int j;
j = 0;
CHECK_FOR_DATA();
/* Since we don't know how long it's been. */
if (!!flag)
{
TRANSMIT_BYTE(0x7E);
}
for (i = 0; i < g_Transmit_Length; i++)
{
/* we only need to check once every 31 characters, since RX and TX
* run at about the same speed, and our RX FIFO is 64 characters
*/
if ((i & 31) == 31) CHECK_FOR_DATA();
ch = g_Transmit_Buffer[i];
if (ch == 0x7E || ch == 0x7D)
{
TRANSMIT_BYTE(0x7D);
TRANSMIT_BYTE(0x20 ^ ch); /*lint !e734 */
}
else
{
TRANSMIT_BYTE(ch); /*lint !e734 */
}
}
CHECK_FOR_DATA();
TRANSMIT_BYTE(0x7E);
#if 0
/* Hack for USB protocol. If we have an exact multiple of the USB frame
* size, then the last frame will not be sent out. The USB standard says
* that a "short packet" needs to be sent to flush the data. Two flag
* characters can serve as the short packet. Doing it this way, we only
* perform this test once on every entire packet from the target, so the
* over head is not too much.
*/
if ((j%512) == 0)
{
TRANSMIT_BYTE (0x7E);
TRANSMIT_BYTE (0x7E);
}
#endif
return (qusb_noblock_write(stream_usb_handle, stream_tx_buf, j, j, 3000, 1) == j) ? 0 : -1;
}
static int remove_escape_hdlc_flag(unsigned char *buffer, int len)
{
int i = 0;
int index = 0;
int escape = 0;
// dump_buffer(buffer, len);
if (len == 0) return 0;
// ignore the first HDLC FLAG bytes
while (buffer[i] == 0x7e)
{
i++;
}
// all bytes is HDLC FLAG
if (i == len) return 0;
for (; i < len; i++)
{
if (buffer[i] == 0x7D)
{
escape = 1;
continue;
}
if (escape == 1)
{
escape = 0;
buffer[i] ^= 0x20;
}
buffer[index++] = buffer[i];
}
buffer[index] = 0;
// dump_buffer(buffer, index);
return index;
}
static int receive_packet(void)
{
int bytesread = 0;
unsigned char *buff = g_Receive_Buffer;
if (buff == NULL)
{
return -1;
}
int idx = 0;
do
{
bytesread =
qusb_noblock_read(stream_usb_handle, &buff[idx], MAX_RECEIVE_BUFFER_SIZE, 0, 3000);
if (bytesread == 0)
{
// timeout may be error
dbg_time("%s timeout\n", __FUNCTION__);
break;
}
// dump_buffer(&buff[idx], bytesread);
idx += bytesread;
if (buff[idx - 1] == 0x7e)
{
// check the packet whether valid.
g_Receive_Bytes = remove_escape_hdlc_flag(buff, idx);
if (g_Receive_Bytes == 0)
{
continue;
}
else
{
return 1;
}
}
} while (1);
return 0;
}
static int handle_hello(void)
{
static const char host_header[] = "QCOM fast download protocol host";
// static const char target_header[] = "QCOM fast download protocol targ";
// char string1[64];
// int size;
int err;
dbg_time("%s\n", __func__);
memset(&g_Transmit_Buffer[0], 0, sizeof(g_Transmit_Buffer));
g_Transmit_Buffer[HELLO_CMD_OFFSET] = HELLO_REQ;
memcpy(&g_Transmit_Buffer[HELLO_MAGIC_NUM_OFFSET], host_header, 32);
g_Transmit_Buffer[HELLO_MAX_VER_OFFSET] = STREAM_DLOAD_MAX_VER;
g_Transmit_Buffer[HELLO_MIN_VER_OFFSET] = STREAM_DLOAD_MIN_VER;
g_Transmit_Buffer[HELLO_MAX_DATA_SZ_1_OFFSET] = 0;
g_Transmit_Length = 36;
compute_reply_crc();
send_packet(1);
int timeout = 5;
do
{
err = receive_packet();
if (err == 1)
{
switch (g_Receive_Buffer[0])
{
case 0x02: return 1;
case 0x0d: continue;
default:
// dump_buffer(g_Receive_Buffer, 64);
return 0;
}
}
else if (err == -1)
{
dbg_time("error = %d, strerr = %s\n", errno, strerror(errno));
return 0;
}
timeout--;
} while (timeout);
return 0;
}
static int handle_security_mode(unsigned char trusted)
{
dbg_time("%s trusted = %d\n", __func__, trusted);
compose_packet(0x17, &trusted, 1, NULL, 0);
compute_reply_crc();
send_packet(1);
int timeout = 5;
do
{
if (receive_packet() == 1)
{
switch (g_Receive_Buffer[0])
{
case 0x18: return 1;
default: return 0;
}
}
else
{
timeout--;
if (timeout == 0)
{
dbg_time("%s timeout\n", __FUNCTION__);
break; // return 0; -Werror,-Wunreachable-code-return
}
}
} while (1);
return 0;
}
/*
set download flag in module, quectel custom command,
if flag : reboot, module will enter DM
if not flag: reboot normal
*/
static int handle_quectel_download_flag(unsigned char mode)
{
// byte mode = 1;
compose_packet(0x60, &mode, 1, NULL, 0);
compute_reply_crc();
send_packet(1);
int timeout = 5;
do
{
if (receive_packet() == 1)
{
switch (g_Receive_Buffer[0])
{
case 0x61:
switch (g_Receive_Buffer[1])
{
case 0x00: return 1;
default: return 0;
}
break;
case 0x0E: dbg_time("Invalid command"); return 2;
default: dump_buffer(g_Receive_Buffer, 64); return 0;
}
}
else
{
timeout--;
if (timeout == 0)
{
dbg_time("%s timeout\n", __FUNCTION__);
return 0;
}
}
} while (1);
}
static const char *stream_firehose_dir;
static int stread_fread(const char *filename, void **pp_filebuf)
{
int filesize = 0;
FILE *fp;
char fullpath[MAX_PATH * 2];
snprintf(fullpath, sizeof(fullpath), "%.240s/../%.240s", stream_firehose_dir, filename);
fp = fopen(fullpath, "rb");
if (fp == NULL)
{
dbg_time("fail to fope %s, errno: %d (%s)\n", fullpath, errno, strerror(errno));
return 0;
}
fseek(fp, 0, SEEK_END);
filesize = ftell(fp);
*pp_filebuf = malloc(filesize);
if (pp_filebuf == NULL)
{
dbg_time("fail to malloc %d, errno: %d (%s)\n", filesize, errno, strerror(errno));
if (fp)
{
fclose(fp);
fp = NULL;
}
return 0;
}
fseek(fp, 0, SEEK_SET);
filesize = fread(*pp_filebuf, 1, filesize, fp);
fclose(fp);
dbg_time("%s filename=%s, filesize=%d\n", __func__, filename, filesize);
return filesize;
}
static int handle_parti_tbl(unsigned char override)
{
int timeout = 5;
int filesize;
void *filebuf;
const char *partition_path = "partition.mbn";
dbg_time("%s override = %d\n", __func__, override);
filesize = stread_fread(partition_path, &filebuf);
if (filesize <= 0)
{
if (filebuf)
{
free(filebuf);
filebuf = NULL;
}
return 0;
}
compose_packet(0x19, &override, 1, filebuf, filesize);
compute_reply_crc();
send_packet(1);
free(filebuf);
do
{
if (receive_packet() == 1)
{
dbg_time("handle_parti_tbl command = %02x, status = %02x\n", g_Receive_Buffer[0],
g_Receive_Buffer[1]);
switch (g_Receive_Buffer[0])
{
case 0x1a:
switch (g_Receive_Buffer[1])
{
case 0x00: return 1;
case 0x01: // 0x1 this means that the original partition is different from
// the current partition,try to send partition
return 0;
case 0x02: // 0x2 Partition table format not recognized, does not accept
// override
return 0;
case 0x03: // 0x3 Erase operation failed
return 0;
break;
default: return 0;
}
default: return 0;
}
}
else
{
timeout--;
if (timeout == 0)
{
dbg_time("%s timeout\n", __FUNCTION__);
return 0;
}
}
} while (1);
}
static int handle_reset(void)
{
dbg_time("%s\n", __func__);
compose_packet(0x0b, NULL, 0, NULL, 0);
compute_reply_crc();
send_packet(1);
#if 1
return 1;
#else
int timeout = 5;
do
{
if (receive_packet() == 1)
{
switch (g_Receive_Buffer[0])
{
case 0x0c: return 1;
case 0x0d: continue;
default: dump_buffer(g_Receive_Buffer, 64); return 0;
}
}
else
{
timeout--;
if (timeout == 0)
{
dbg_time("%s timeout\n", __FUNCTION__);
return 0;
}
}
} while (1);
#endif
}
/******pkt_open_multi_image*******/
static void pkt_open_multi_image(unsigned char mode, unsigned char *data, uint32_t size)
{
compose_packet(0x1b, &mode, 1, data, size);
compute_reply_crc();
}
static int handle_openmulti(uint32_t size, unsigned char *data)
{
int timeout = 5;
unsigned char mode = 0x0e;
pkt_open_multi_image(mode, data, size);
send_packet(1);
do
{
if (receive_packet() == 1)
{
switch (g_Receive_Buffer[0])
{
case 0x1c: return 1;
case 0x0d: continue;
default: return 0;
}
}
else
{
timeout--;
if (timeout == 0)
{
dbg_time("%s timeout\n", __FUNCTION__);
break;
}
}
} while (1);
return 0;
}
/******pkt_write_multi_image*******/
static void pkt_write_multi_image(uint32_t addr, unsigned char *data, uint16_t size)
{
unsigned char parameter[4] = {(unsigned char)(addr)&0xff, (unsigned char)(addr >> 8) & 0xff,
(unsigned char)(addr >> 16) & 0xff,
(unsigned char)(addr >> 24) & 0xff};
compose_packet(0x07, parameter, 4, data, size);
compute_reply_crc();
}
static int handle_write(unsigned char *data, uint32_t size)
{
// uint32_t total_size;
uint32_t addr = 0;
uint32_t writesize;
uint32_t buffer_size = 1024;
// int loop = 1;
int retry_cnt = 3; // if send failed,send again
int ret;
// total_size = size;
while (size)
{
writesize = (size < buffer_size) ? size : buffer_size;
pkt_write_multi_image(addr, data, writesize);
start_send_packet:
ret = send_packet(1);
if (0 != ret)
{
dbg_time("io read/write failed\n");
return 0;
}
if (receive_packet() == 1)
{
switch (g_Receive_Buffer[0])
{
case 0x08:
size -= writesize;
addr += writesize;
// retry_cnt=5;
break;
default:
goto retry_send_packet;
// return 0;
}
}
else
{
retry_send_packet:
retry_cnt--;
if (retry_cnt > 0)
{
goto start_send_packet;
}
else
{
dbg_time("value is [0x%02x]", g_Receive_Buffer[0]);
return 0;
}
}
}
return 1;
}
/******PARTITION*******/
static int handle_close(void)
{
int timeout = 5;
compose_packet(0x15, NULL, 0, NULL, 0);
compute_reply_crc();
send_packet(1);
do
{
if (receive_packet() == 1)
{
switch (g_Receive_Buffer[0])
{
case 0x16: return 1;
default: return 0;
}
}
else
{
timeout--;
if (timeout == 0)
{
dbg_time("%s timeout\n", __FUNCTION__);
break;
}
}
} while (1);
return 0;
}
static int do_flash_mbn(const char *partion, const char *filepath)
{
int result = false;
void *filebuf = NULL;
int filesize = 0;
dbg_time("%s %s\n", __func__, partion);
if (filepath)
{
filesize = stread_fread(filepath, &filebuf);
if (filesize <= 0)
{
if (filebuf)
{
free(filebuf);
filebuf = NULL;
}
return 0;
}
}
else
{
filesize = 4 * 1024;
filebuf = (unsigned char *)malloc(filesize);
if (filebuf == NULL)
{
return 0;
}
memset(filebuf, 0x00, filesize);
}
result = handle_openmulti(strlen(partion) + 1, (unsigned char *)partion);
if (result == false)
{
dbg_time("%s open failed\n", partion);
goto __fail;
}
dbg_time("sending '%s' (%dKB)\n", partion, (int)(filesize / 1024));
result = handle_write(filebuf, filesize);
if (result == false)
{
dbg_time("%s download failed\n", partion);
goto __fail;
}
result = handle_close();
if (result == false)
{
dbg_time("%s close failed.\n", partion);
goto __fail;
}
dbg_time("OKAY\n");
__fail:
free(filebuf);
return result;
}
int stream_download(const char *firehose_dir, void *usb_handle, unsigned qusb_zlp_mode)
{
(void)qusb_zlp_mode;
stream_usb_handle = usb_handle;
stream_firehose_dir = firehose_dir;
if (handle_hello() == false)
{
dbg_time("Send hello command fail\n");
return false;
}
/*
hello packet will set dload flag in module, when upgrade interrup, restart module,module will
enter dm(quectel sbl)
*/
if (handle_security_mode(1) == false)
{
dbg_time("Send trust command fail\n");
return false;
}
if (handle_parti_tbl(0) == false)
{
dbg_time("----------------------------------\n");
dbg_time("Detect partition mismatch.\n");
dbg_time("Download parition with override.\n");
dbg_time("----------------------------------\n");
if (handle_parti_tbl(1) == false)
{
dbg_time("override failed. \n");
return false;
}
/*
partition is not match, the download flag will be clear, so set it again, reset will clear
it
*/
if (handle_quectel_download_flag(1) == false)
{
dbg_time("Set Quectel download flag failed\n");
}
else
{
dbg_time("Set Quectel download flag successfully\n");
}
}
#if 1
if (do_flash_mbn("0:SBL", "sbl1.mbn") == false)
{
return false;
}
#endif
if (handle_reset() == false)
{
dbg_time("Send reset command failed\n");
return false;
}
dbg_time("%s successful\n", __func__);
return true;
}
// retrieve module soft revision
typedef struct
{
unsigned char cmd_code;
unsigned char version;
unsigned char reserved[2];
unsigned char msm[4];
unsigned char mobile_modle_number[4];
unsigned char mobile_software_revision[1];
} __attribute__((packed)) extended_build_id_response_t;
int retrieve_soft_revision(void *usb_handle, uint8_t *mobile_software_revision, unsigned length)
{
/*
80-v1294-1_yyd_serial_interface_control_document_(icd)_for_cdma_dual-mode_subscriber_station_data
3.4.122 Extended Build ID
*/
uint8_t req1[] = {0x7E, 0x7C, 0x93, 0x49, 0x7E};
int ret;
uint8_t *rx_buff = malloc(2048);
memset(mobile_software_revision, 0x00, length);
if (rx_buff == NULL) return 0;
ret = qusb_noblock_write(usb_handle, req1, sizeof(req1), sizeof(req1), 1000, 0);
if (ret > 0)
{
ret = qusb_noblock_read(usb_handle, rx_buff, 2048, 1, 3000);
if (ret > 0)
{
if (rx_buff[0] == 0x7C && rx_buff[ret - 1] == 0x7E)
{
extended_build_id_response_t *rsp = (extended_build_id_response_t *)rx_buff;
(void)length;
memcpy(mobile_software_revision, rsp->mobile_software_revision,
strlen((const char *)rsp->mobile_software_revision));
}
}
}
free(rx_buff);
return (mobile_software_revision[0] != '\0');
}

View File

@ -0,0 +1,381 @@
/*
Copyright 2023 Quectel Wireless Solutions Co.,Ltd
Quectel hereby grants customers of Quectel a license to use, modify,
distribute and publish the Software in binary form provided that
customers shall have no right to reverse engineer, reverse assemble,
decompile or reduce to source code form any portion of the Software.
Under no circumstances may customers modify, demonstrate, use, deliver
or disclose any portion of the Software in source code form.
*/
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <termios.h>
#include <dirent.h>
#include <pthread.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <poll.h>
#include <netinet/in.h>
#include <linux/un.h>
#include <linux/usbdevice_fs.h>
#include <linux/version.h>
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20)
#include <linux/usb/ch9.h>
#else
#include <linux/usb_ch9.h>
#endif
//#include <asm/byteorder.h>
#include "usb_linux.h"
#include <endian.h> //for __BYTE_ORDER
char *inet_ntoa(struct in_addr in);
#define dprintf dbg_time
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX_USBFS_BULK_IN_SIZE (4 * 1024)
#define MAX_USBFS_BULK_OUT_SIZE (16 * 1024)
static uint32_t cpu_to_le32(uint32_t v32)
{
uint32_t tmp = v32;
#if __BYTE_ORDER == __LITTLE_ENDIAN
#else
unsigned char *s = (unsigned char *)(&v32);
unsigned char *d = (unsigned char *)(&tmp);
d[0] = s[3];
d[1] = s[2];
d[2] = s[1];
d[3] = s[0];
#endif
return tmp;
}
#define le32_to_cpu(_v32) cpu_to_le32(_v32)
static int qusb_control[2];
static int noblock_full_read(int fd, void *pbuf, ssize_t size)
{
ssize_t cur = 0;
while (cur < size)
{
ssize_t ret = read(fd, (char *)pbuf + cur, size - cur);
if (ret > 0)
cur += ret;
else if (ret < 0 && errno == EAGAIN)
{
struct pollfd pollfds[] = {{fd, POLLIN, 0}};
poll(pollfds, 1, -1);
if (pollfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) break;
}
else
{
dprintf("fd=%d read=%zd, errno: %d (%s)\n", fd, ret, errno, strerror(errno));
break;
}
}
if (cur != size)
{
dprintf("%s fd=%d cur=%zd, size=%zd\n", __func__, fd, cur, size);
}
return cur;
}
static ssize_t noblock_full_write(int fd, const void *pbuf, ssize_t size)
{
ssize_t cur = 0;
while (cur < size)
{
ssize_t ret = write(fd, (char *)pbuf + cur, size - cur);
if (ret > 0)
cur += ret;
else if (ret <= 0 && errno == EAGAIN)
{
struct pollfd pollfds[] = {{fd, POLLOUT, 0}};
poll(pollfds, 1, -1);
if (pollfds[0].revents & (POLLERR | POLLHUP | POLLNVAL)) break;
}
else
{
dprintf("fd=%d write=%zd, errno: %d (%s)\n", fd, ret, errno, strerror(errno));
break;
}
}
if (cur != size)
{
dprintf("%s fd=%d cur=%zd, size=%zd\n", __func__, fd, cur, size);
}
return cur;
}
static void *usb_bulk_read_thread(void *arg)
{
const void *usb_handle = arg;
void *buf = malloc(MAX_USBFS_BULK_IN_SIZE);
int fd = qusb_control[1];
if (buf == NULL) return NULL;
while (usb_handle)
{
int count = qusb_noblock_read(usb_handle, buf, MAX_USBFS_BULK_IN_SIZE, 1, 30000);
if (count > 0)
{
count = write(fd, buf, count);
count = read(fd, buf, 32); // wait usb2tcp_main read
if (count <= 0)
{
dprintf("read=%d\n", count);
break;
}
}
else if (count <= 0)
{
break;
}
}
close(fd);
free(buf);
return NULL;
}
static int qusb_open(const void *usb_handle)
{
int fd = -1;
pthread_t thread_id;
pthread_attr_t usb_thread_attr;
pthread_attr_init(&usb_thread_attr);
pthread_attr_setdetachstate(&usb_thread_attr, PTHREAD_CREATE_DETACHED);
socketpair(AF_LOCAL, SOCK_STREAM, 0, qusb_control);
pthread_create(&thread_id, &usb_thread_attr, usb_bulk_read_thread, (void *)usb_handle);
fd = qusb_control[0];
// pthread_attr_destroy(&usb_thread_attr); //aaron 2023.07.27
return fd;
}
static ssize_t qusb_read(int fd, void *pbuf, size_t size) { return read(fd, pbuf, size); }
static int create_tcp_server(int socket_port)
{
int sockfd = -1;
int reuse_addr = 1;
struct sockaddr_in sockaddr;
dprintf("%s tcp_port=%d\n", __func__, socket_port);
/*Create server socket*/
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd <= 0) return sockfd;
memset(&sockaddr, 0, sizeof(sockaddr));
sockaddr.sin_family = AF_INET;
sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
sockaddr.sin_port = htons(socket_port);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse_addr, sizeof(reuse_addr));
if (bind(sockfd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) < 0)
{
close(sockfd);
dprintf("%s bind %d errno: %d (%s)\n", __func__, socket_port, errno, strerror(errno));
return -1;
}
return sockfd;
}
static int wait_client_connect(int server_fd)
{
int client_fd = -1;
unsigned char addr[128];
socklen_t alen = sizeof(addr);
dprintf("%s\n", __func__);
listen(server_fd, 1);
client_fd = accept(server_fd, (struct sockaddr *)addr, &alen);
if (client_fd <= 0) return client_fd;
if (client_fd > 0)
{
struct sockaddr_in *addr_in = (struct sockaddr_in *)addr;
dprintf("clientfd = %d %s:%d connect\n", client_fd, inet_ntoa(addr_in->sin_addr),
addr_in->sin_port);
}
return client_fd;
}
int usb2tcp_main(const void *usb_handle, int tcp_port, unsigned qusb_zlp_mode)
{
void *pbuf = malloc(MAX_USBFS_BULK_OUT_SIZE);
int server_fd = -1, client_fd = -1, usb_fd = -1, size = -1;
TLV_USB tlv_usb;
if (pbuf == NULL) return -1;
server_fd = create_tcp_server(tcp_port);
dprintf("server_fd=%d\n", server_fd);
if (server_fd <= 0)
{
dprintf("Fail create_tcp_server\n");
goto _out;
}
if (client_fd <= 0)
{
client_fd = wait_client_connect(server_fd);
if (client_fd < 0)
{
dprintf("Fail wait_client_connect\n");
goto _out;
}
}
usb_fd = qusb_open(usb_handle);
dprintf("usb_fd = %d\n", usb_fd);
tlv_usb.tag = cpu_to_le32(Q_USB2TCP_VERSION);
tlv_usb.length = cpu_to_le32(12);
tlv_usb.idVendor = cpu_to_le32(0x05c6);
tlv_usb.idProduct = cpu_to_le32(0x9008);
tlv_usb.interfaceNum = cpu_to_le32(1);
if (write(client_fd, &tlv_usb, sizeof(tlv_usb)) == -1)
{
};
fcntl(usb_fd, F_SETFL, fcntl(usb_fd, F_GETFL) | O_NONBLOCK);
fcntl(client_fd, F_SETFL, fcntl(client_fd, F_GETFL) | O_NONBLOCK);
while (usb_fd > 0 && client_fd > 0)
{
struct pollfd pollfds[] = {{usb_fd, POLLIN, 0}, {client_fd, POLLIN, 0}};
int ne, ret, nevents = sizeof(pollfds) / sizeof(pollfds[0]);
do
{
ret = poll(pollfds, nevents, -1);
} while (ret < 0 && errno == EINTR);
if (ret <= 0)
{
dprintf("%s poll=%d, errno: %d (%s)\n", __func__, ret, errno, strerror(errno));
goto _hangup;
}
if (pollfds[0].revents & (POLLERR | POLLHUP | POLLNVAL))
{
dprintf("%s poll usb_fd = %d, revents = %04x\n", __func__, usb_fd, pollfds[0].revents);
goto _hangup;
}
if (pollfds[1].revents & (POLLERR | POLLHUP | POLLNVAL))
{
dprintf("%s poll client_fd = %d, revents = %04x\n", __func__, client_fd,
pollfds[1].revents);
goto _hangup;
}
for (ne = 0; ne < nevents; ne++)
{
int fd = pollfds[ne].fd;
TLV tlv = {Q_USB2TCP_VERSION, 0};
if ((pollfds[ne].revents & POLLIN) == 0) continue;
if (fd == usb_fd)
{
size = qusb_read(usb_fd, pbuf, MAX_USBFS_BULK_IN_SIZE);
if (size <= 0)
{
dprintf("usb_fd=%d read=%d, errno: %d (%s)\n", fd, size, errno,
strerror(errno));
goto _hangup;
;
}
if (write(usb_fd, pbuf, 1) == -1)
{
}; // wakeup usb_bulk_read_thread
tlv.tag = cpu_to_le32(Q_USB2TCP_VERSION);
tlv.length = cpu_to_le32(size);
if (sizeof(tlv) != noblock_full_write(client_fd, &tlv, sizeof(tlv)))
{
goto _hangup;
break;
}
if (size != noblock_full_write(client_fd, pbuf, size))
{
goto _hangup;
break;
}
}
else if (fd == client_fd)
{
size = noblock_full_read(client_fd, &tlv, sizeof(tlv));
if (size != sizeof(tlv))
{
dprintf("client_fd=%d read=%d, errno: %d (%s)\n", fd, size, errno,
strerror(errno));
goto _hangup;
}
if (le32_to_cpu(tlv.tag) != Q_USB2TCP_VERSION)
{
break;
}
size = le32_to_cpu(tlv.length);
if (size != noblock_full_read(client_fd, pbuf, size))
{
goto _hangup;
break;
}
qusb_noblock_write(usb_handle, pbuf, size, size, 3000, qusb_zlp_mode);
}
}
}
_hangup:
if (usb_fd > 0)
{
close(usb_fd);
usb_fd = -1;
}
if (client_fd > 0)
{
close(client_fd);
client_fd = -1;
}
_out:
if (server_fd > 0)
{
close(server_fd);
server_fd = -1;
}
free(pbuf);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,193 @@
/*
Copyright 2023 Quectel Wireless Solutions Co.,Ltd
Quectel hereby grants customers of Quectel a license to use, modify,
distribute and publish the Software in binary form provided that
customers shall have no right to reverse engineer, reverse assemble,
decompile or reduce to source code form any portion of the Software.
Under no circumstances may customers modify, demonstrate, use, deliver
or disclose any portion of the Software in source code form.
*/
#ifndef __QFIREHOSE_USB_LINUX_H__
#define __QFIREHOSE_USB_LINUX_H__
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/time.h>
#include <time.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#define MAX_PATH 256
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define ZIP_INFO "/tmp/zip_info.txt"
#define ZIP_PROCESS_INFO "/tmp/zip_process_info.txt"
#define safe_free(p) \
do \
{ \
if (p != NULL) \
{ \
free((void *)p); \
p = NULL; \
} \
} while (0)
extern char zip_cmd_buf[512];
extern int g_is_module_adb_entry_edl;
typedef struct module_sys_info
{
/*
MAJOR=189
MINOR=1
DEVNAME=bus/usb/001/002
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=2c7c/415/318
TYPE=239/2/1
BUSNUM=001
*/
// char sys_path[MAX_PATH];
int MAJOR;
int MINOR;
char DEVNAME[64];
char DEVTYPE[64];
char PRODUCT[64];
} MODULE_SYS_INFO;
void *qusb_noblock_open(const char *module_sys_path, int *idVendor, int *idProduct, int *interfaceNum);
int qusb_noblock_close(void *handle);
int qusb_noblock_write(const void *handle, void *pbuf, int max_size, int min_size, int timeout_msec, int need_zlp);
int qusb_noblock_read(const void *handle, void *pbuf, int max_size, int min_size, int timeout_msec);
int qusb_read_speed_atime(const char *module_sys_path, struct timespec *out_time, int *out_speed);
int qfile_find_file(const char *dir, const char *prefix, const char *suffix, char **filename);
#define errno_nodev() (errno == ENOENT || errno == ENODEV)
// void dbg_time (const char *fmt, ...);
const char *firehose_get_time(void);
extern FILE *loghandler;
#ifdef FH_DEBUG
#define dbg_time(fmt, args...) \
do \
{ \
fprintf(stdout, "[%15s-%04d]%s: " fmt, __FILE__, __LINE__, firehose_get_time(), ##args); \
fflush(stdout); \
if (loghandler) fprintf(loghandler, "[%15s-%04d]%s: " fmt, __FILE__, __LINE__, firehose_get_time(), ##args); \
} while (0);
#else
#define dbg_time(fmt, args...) \
do \
{ \
fprintf(stdout, "%s: " fmt, firehose_get_time(), ##args); \
fflush(stdout); \
if (loghandler) fprintf(loghandler, "%s: " fmt, firehose_get_time(), ##args); \
} while (0);
#endif
double get_now();
void get_duration(double start);
int update_transfer_bytes(long long bytes_cur);
void set_transfer_allbytes(long long bytes);
int auto_find_quectel_modules(char *module_sys_path, unsigned size, const char *product, const struct timespec *atime);
void quectel_get_syspath_name_by_ttyport(const char *module_port_name, char *module_sys_path, unsigned size);
void quectel_get_ttyport_by_syspath(const char *module_sys_path, char *module_port_name, unsigned size);
#define error_return() \
do \
{ \
dbg_time("%s %s %d fail\n", __FILE__, __func__, __LINE__); \
return __LINE__; \
} while (0)
extern int edl_pcie_mhifd;
#define IOCTL_BHI_GETDEVINFO 0x8BE0 + 1
#define IOCTL_BHI_WRITEIMAGE 0x8BE0 + 2
typedef unsigned int ULONG;
typedef struct _bhi_info_type
{
ULONG bhi_ver_minor;
ULONG bhi_ver_major;
ULONG bhi_image_address_low;
ULONG bhi_image_address_high;
ULONG bhi_image_size;
ULONG bhi_rsvd1;
ULONG bhi_imgtxdb;
ULONG bhi_rsvd2;
ULONG bhi_msivec;
ULONG bhi_rsvd3;
ULONG bhi_ee;
ULONG bhi_status;
ULONG bhi_errorcode;
ULONG bhi_errdbg1;
ULONG bhi_errdbg2;
ULONG bhi_errdbg3;
ULONG bhi_sernum;
ULONG bhi_sblantirollbackver;
ULONG bhi_numsegs;
ULONG bhi_msmhwid[6];
ULONG bhi_oempkhash[48];
ULONG bhi_rsvd5;
} BHI_INFO_TYPE, *PBHI_INFO_TYPE;
enum MHI_EE
{
MHI_EE_PBL = 0x0, /* Primary Boot Loader */
MHI_EE_SBL = 0x1, /* Secondary Boot Loader */
MHI_EE_AMSS = 0x2, /* AMSS Firmware */
MHI_EE_RDDM = 0x3, /* WIFI Ram Dump Debug Module */
MHI_EE_WFW = 0x4, /* WIFI (WLAN) Firmware */
MHI_EE_PT = 0x5, /* PassThrough, Non PCIe BOOT (PCIe is BIOS locked, not used for boot */
MHI_EE_EDL = 0x6, /* PCIe enabled in PBL for emergency download (Non PCIe BOOT) */
MHI_EE_FP = 0x7, /* FlashProg, Flash Programmer Environment */
MHI_EE_BHIE = MHI_EE_FP,
MHI_EE_UEFI = 0x8, /* UEFI */
MHI_EE_DISABLE_TRANSITION = 0x9,
MHI_EE_MAX
};
int qpcie_open(const char *firehose_dir, const char *firehose_mbn, const char *module_port_name);
#define Q_USB2TCP_VERSION 0x12345678
typedef struct
{
int tag;
int length;
int value[];
} TLV;
typedef struct
{
int tag;
int length;
int idVendor;
int idProduct;
int interfaceNum;
} TLV_USB;
typedef struct
{
char zip_file_name_backup[128];
char zip_file_dir_backup[256];
} file_name_backup_count;
typedef struct
{
int file_name_count;
file_name_backup_count file_backup_c[256]; // smart SA885GAPNA number of image file is 96
} file_name_backup;
extern file_name_backup file_name_b;
extern int is_upgrade_fimeware_zip_7z;
extern int is_firehose_zip_7z_name_exit;
extern int is_upgrade_fimeware_only_zip;
extern unsigned int g_from_ecm_to_rndis;
#endif

View File

@ -27,6 +27,7 @@ LUCI_DEPENDS:=+luci-compat \
+usbutils \
+PACKAGE_luci-app-qmodem_INCLUDE_ADD_PCI_SUPPORT:kmod-pcie_mhi \
+PACKAGE_luci-app-qmodem_INCLUDE_ADD_PCI_SUPPORT:pciutils \
+PACKAGE_luci-app-qmodem_INCLUDE_ADD_QFIREHOSE_SUPPORT:qfirehose \
+PACKAGE_luci-app-qmodem_USE_TOM_CUSTOMIZED_QUECTEL_CM:quectel-CM-5G-M \
+PACKAGE_luci-app-qmodem_USING_QWRT_QUECTEL_CM_5G:quectel-CM-5G \
+PACKAGE_luci-app-qmodem_USING_NORMAL_QUECTEL_CM:quectel-cm \
@ -69,6 +70,10 @@ endchoice
config PACKAGE_luci-app-qmodem_INCLUDE_ADD_PCI_SUPPORT
bool "Add PCIe Modem SUPPORT"
default n
config PACKAGE_luci-app-qmodem_INCLUDE_ADD_QFIREHOSE_SUPPORT
bool "Add Qfirehose SUPPORT"
default n
endef
define Package/luci-app-qmodem_with_lua_index_page