Hi,
我移植了hci的协议在A板上测试,B板上下载了ota_firmware_upgrade的程序。A板上发起了19 01 03 07 00 00 88 88 88 88 35 da(connect)的命令,并且与B板成功链接。截图如下
接下来的一步应该是由A板发起WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOD命令,但我不知道如何进行。
1. 是要发GATT Command Write这个命令吗?
2. GATT Command Write这个命令怎么写?19 02 06 06 00 01 00 01 00 04 00?
01 00:Attribute handle 不知道怎么填写
04 00:Data不知道怎么填写
3. 测了一下命令19 02 06 06 00 01 00 00 ff 01 02,回复是WICED_BT_GATT_WRITE_NOT_PERMIT
已解决! 转到解答。
Hi,
对于如何发起WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOD命令,以及如何在A板如何执行OTA升级流程,您可以参考WICED Studio里面的ota_firmware_upgrade部分提供的peer_apps的代码(前提是您的A板依然是通过蓝牙去连接B板,去升级B板的固件)。
比如,‘<wiced_sdk>/20706-A2_Bluetooth/apps/snip/ota_firmware_upgrade/peer_apps'下面提供了Android版本和Windows版本的升级端demo。Android版本的代码比较清晰,有关于如何发送命令的函数如下:
void SendWsUpgradeCommand(int command)
{
byte[] buffer = new byte[1];
buffer[0] = (byte) command;
writeOTAControlPointCharacteristic(buffer);
}void SendWsUpgradeCommand(int command, int value)
{
byte[] buffer = new byte[5];
buffer[0] = (byte) command;
buffer[1] = (byte) (value & 0xff);
buffer[2] = (byte) ((value >> 😎 & 0xff);
buffer[3] = (byte) ((value >> 16) & 0xff);
buffer[4] = (byte) ((value >> 24) & 0xff);
writeOTAControlPointCharacteristic(buffer);
}
然后在别处执行的时候,便会调用:‘SendWsUpgradeCommand(WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOAD);’
通过查证’WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOAD‘的定义,可发现其就仅仅是一个byte的int类型'1'.
所以关于发送这个命令,其实就是往OTA的ControlPoint的UUID所标识的GATT数据库句柄写入int数据'1'即可。而这个ControlPoint,可以在Constant.java里面找到具体的定义:
public static final UUID UPGRADE_CHARACTERISTIC_CONTROL_POINT_UUID = UUID.fromString("a3dd50bf-f7a7-4e99-838e-570a086c661b");
如果您的确是这样写入的,但依然遇到问题,那请您再次检查是否严格按照OTA升级的流程来发送命令和切换状态。具体的流程,您也可以参照这个Android的PeerApp中的这个代码流程:
void ProcessProgress(int state)
{
int total = m_PatchSize;
int param = 0;if (state == WS_UPGRADE_STATE_WAIT_FOR_READY_FOR_DOWNLOAD)
{
Log.d(TAG, "ProcessProgress Ready For Download");
total = m_PatchSize;
mLabelOTAStatus.setText("Transfer");
mButtonOTAUpdate.setText("Abort");
}
else if (state == WS_UPGRADE_STATE_DATA_TRANSFER)
{
param = m_offset;
String status = "ProcessProgress offset: " + m_offset + " of total: " + m_PatchSize;
Log.d(TAG, status);
mLabelOTAStatus.setText(status);if (param == total)
{
Log.d(TAG, "ProcessProgress - Sent Entire file param: " + param + " total: " + total);
runOnUiThread(new Runnable() {
@Override
public void run() {
ProcessEvent(WS_UPGRADE_START_VERIFICATION);
}
});mLabelOTAStatus.setText("Download Verification");
}
}
else if (state == WS_UPGRADE_STATE_VERIFIED)
{
Log.d(TAG, "ProcessProgress verified");
long elapsed_time = Calendar.getInstance().getTimeInMillis() - m_time;
String status = "Success " + (elapsed_time / 1000) + "sec (" + (m_PatchSize * 8 * 1000 / elapsed_time) + "kbps)";
mLabelOTAStatus.setText(status);
mButtonOTAUpdate.setText("Update");
}
else if (state == WS_UPGRADE_STATE_ABORTED)
{
Log.d(TAG, "ProcessProgress Aborted");
mLabelOTAStatus.setText("Aborted");
mButtonOTAUpdate.setText("Update");
}
}void ProcessEvent(int Event)
{
Log.d(TAG, "ProcessEvent state : " + m_state + " Event: " + Event);switch (m_state)
{
case WS_UPGRADE_STATE_IDLE:
m_bConnected = true;
if (Event == WS_UPGRADE_CONNECTED)
{
if(m_PatchSize <= 0 || m_Patch == null)
{
mLabelOTAStatus.setText("Invalid Image File");
return;
}
// register for notifications and indications with the status
RegisterOTANotification(true);
SendWsUpgradeCommand(WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOAD);
m_state = WS_UPGRADE_STATE_WAIT_FOR_READY_FOR_DOWNLOAD;//PostMessage(m_hWnd, WM_PROGRESS, (WPARAM)WS_UPGRADE_STATE_WAIT_FOR_READY_FOR_DOWNLOAD, (LPARAM)m_PatchSize);
UpdateProgress();
}
break;case WS_UPGRADE_STATE_WAIT_FOR_READY_FOR_DOWNLOAD:
if (Event == WS_UPGRADE_RESPONSE_OK)
{
m_offset = 0;
m_state = WS_UPGRADE_STATE_DATA_TRANSFER;
SendWsUpgradeCommand(WICED_OTA_UPGRADE_COMMAND_DOWNLOAD, (int)m_PatchSize);
}
break;case WS_UPGRADE_STATE_DATA_TRANSFER:
if (Event == WS_UPGRADE_RESPONSE_OK)
{
// Create thread reading unsolicited eventsif(m_bInTransfer == false) {
runOnUiThread(new Runnable() {@Override
public void run() {
m_offset = 0;
m_bInTransfer = true;
SendOTAImageData();
}
});
}
}
else if (Event == WS_UPGRADE_CONTINUE)
{
}
else if (Event == WS_UPGRADE_START_VERIFICATION)
{
m_state = WS_UPGRADE_STATE_VERIFICATION;
SendWsUpgradeCommand(WICED_OTA_UPGRADE_COMMAND_VERIFY, m_crc32);
}
else if (Event == WS_UPGRADE_ABORT)
{
Log.d(TAG, "ProcessEvent state : " + WS_UPGRADE_STATE_DATA_TRANSFER + " Event: " + WS_UPGRADE_ABORT);
m_state = WS_UPGRADE_STATE_ABORTED;
}
break;case WS_UPGRADE_STATE_VERIFICATION:
if (Event == WS_UPGRADE_RESPONSE_OK)
{
Log.d(TAG, "ProcessEvent state : " + WS_UPGRADE_STATE_VERIFICATION + " Event: " + WS_UPGRADE_RESPONSE_OK);
m_state = WS_UPGRADE_STATE_VERIFIED;
UpdateProgress();
}
else if (Event == WS_UPGRADE_RESPONSE_FAILED)
{
Log.d(TAG, "ProcessEvent state : " + WS_UPGRADE_STATE_VERIFICATION + " Event: " + WS_UPGRADE_RESPONSE_FAILED);
m_state = WS_UPGRADE_STATE_ABORTED;
UpdateProgress();
}
break;case WS_UPGRADE_STATE_ABORTED:
if (Event == WS_UPGRADE_RESPONSE_OK)
{
Log.d(TAG, "ProcessEvent state : " + WS_UPGRADE_STATE_ABORTED + " Event: " + WS_UPGRADE_RESPONSE_OK);
UpdateProgress();
}
break;default:
break;
}
}
更具体的需要您深入探究这个Android版本的ota_firwmare_upgrade的代码。通过步进调试,您便可以知道它的全部流程。
<<<<<<<<<<<<<>>>>>>>>>>>>>
Best Regards
C. L.
<<<<<<<<<<<<<>>>>>>>>>>>>>
Did you have a chance to go through wiced_fw_upgrade_library.pdf located in the Doc folder of the SDK? Page 7 described step by step of this sequence.
看过了,所以在按照这个步骤在测试这些命令。但是还是不知道怎么由A板发起WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOD命令
测试步骤如下:
1. 连上后enable notification
2. GATTC_OPTYPE_WRITE event过来后发送WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOD命令
3. 但是GATTC_OPTYPE_WRITE event过来是WICED_BT_GATT_WRITE_NOT_PERMIT
如下是log截图
Hi,
您好,我有点不是很理解您的操作。您是准备把原来的通过蓝牙连接传输的OTA升级改成通过UART等接口来传输吗?
您如果希望把OTA从蓝牙连接通道切换到UART通道,那您上面测试过程里面为什么还要去通过GATT来读写呢?
对于CY的OTA升级设计,GATT的读写只是蓝牙空口的“代名词”和读写接口。所以如果您已经决定放弃使用蓝牙连接来接收固件,那您接下来的操作都应该与GATT无关,亦即您已不需要从GATT接收固件数据包。因为如果您从UART读到固件数据包了,那你就已经获得固件本身了,您不需要又redirect到GATT端去,然后再“被接收”一次。
当然,不是说您的做法不可以。
另外,我看到您的截图,您的AB板之间似乎还是在走蓝牙连接,而不是UART连接。所以我还不很清楚您的操作和您的意图。
期待您的回复噢。
<<<<<<<<<<<<<>>>>>>>>>>>>>
Best regards
C. L.
<<<<<<<<<<<<<>>>>>>>>>>>>>
Hi,
对于如何发起WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOD命令,以及如何在A板如何执行OTA升级流程,您可以参考WICED Studio里面的ota_firmware_upgrade部分提供的peer_apps的代码(前提是您的A板依然是通过蓝牙去连接B板,去升级B板的固件)。
比如,‘<wiced_sdk>/20706-A2_Bluetooth/apps/snip/ota_firmware_upgrade/peer_apps'下面提供了Android版本和Windows版本的升级端demo。Android版本的代码比较清晰,有关于如何发送命令的函数如下:
void SendWsUpgradeCommand(int command)
{
byte[] buffer = new byte[1];
buffer[0] = (byte) command;
writeOTAControlPointCharacteristic(buffer);
}void SendWsUpgradeCommand(int command, int value)
{
byte[] buffer = new byte[5];
buffer[0] = (byte) command;
buffer[1] = (byte) (value & 0xff);
buffer[2] = (byte) ((value >> 😎 & 0xff);
buffer[3] = (byte) ((value >> 16) & 0xff);
buffer[4] = (byte) ((value >> 24) & 0xff);
writeOTAControlPointCharacteristic(buffer);
}
然后在别处执行的时候,便会调用:‘SendWsUpgradeCommand(WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOAD);’
通过查证’WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOAD‘的定义,可发现其就仅仅是一个byte的int类型'1'.
所以关于发送这个命令,其实就是往OTA的ControlPoint的UUID所标识的GATT数据库句柄写入int数据'1'即可。而这个ControlPoint,可以在Constant.java里面找到具体的定义:
public static final UUID UPGRADE_CHARACTERISTIC_CONTROL_POINT_UUID = UUID.fromString("a3dd50bf-f7a7-4e99-838e-570a086c661b");
如果您的确是这样写入的,但依然遇到问题,那请您再次检查是否严格按照OTA升级的流程来发送命令和切换状态。具体的流程,您也可以参照这个Android的PeerApp中的这个代码流程:
void ProcessProgress(int state)
{
int total = m_PatchSize;
int param = 0;if (state == WS_UPGRADE_STATE_WAIT_FOR_READY_FOR_DOWNLOAD)
{
Log.d(TAG, "ProcessProgress Ready For Download");
total = m_PatchSize;
mLabelOTAStatus.setText("Transfer");
mButtonOTAUpdate.setText("Abort");
}
else if (state == WS_UPGRADE_STATE_DATA_TRANSFER)
{
param = m_offset;
String status = "ProcessProgress offset: " + m_offset + " of total: " + m_PatchSize;
Log.d(TAG, status);
mLabelOTAStatus.setText(status);if (param == total)
{
Log.d(TAG, "ProcessProgress - Sent Entire file param: " + param + " total: " + total);
runOnUiThread(new Runnable() {
@Override
public void run() {
ProcessEvent(WS_UPGRADE_START_VERIFICATION);
}
});mLabelOTAStatus.setText("Download Verification");
}
}
else if (state == WS_UPGRADE_STATE_VERIFIED)
{
Log.d(TAG, "ProcessProgress verified");
long elapsed_time = Calendar.getInstance().getTimeInMillis() - m_time;
String status = "Success " + (elapsed_time / 1000) + "sec (" + (m_PatchSize * 8 * 1000 / elapsed_time) + "kbps)";
mLabelOTAStatus.setText(status);
mButtonOTAUpdate.setText("Update");
}
else if (state == WS_UPGRADE_STATE_ABORTED)
{
Log.d(TAG, "ProcessProgress Aborted");
mLabelOTAStatus.setText("Aborted");
mButtonOTAUpdate.setText("Update");
}
}void ProcessEvent(int Event)
{
Log.d(TAG, "ProcessEvent state : " + m_state + " Event: " + Event);switch (m_state)
{
case WS_UPGRADE_STATE_IDLE:
m_bConnected = true;
if (Event == WS_UPGRADE_CONNECTED)
{
if(m_PatchSize <= 0 || m_Patch == null)
{
mLabelOTAStatus.setText("Invalid Image File");
return;
}
// register for notifications and indications with the status
RegisterOTANotification(true);
SendWsUpgradeCommand(WICED_OTA_UPGRADE_COMMAND_PREPARE_DOWNLOAD);
m_state = WS_UPGRADE_STATE_WAIT_FOR_READY_FOR_DOWNLOAD;//PostMessage(m_hWnd, WM_PROGRESS, (WPARAM)WS_UPGRADE_STATE_WAIT_FOR_READY_FOR_DOWNLOAD, (LPARAM)m_PatchSize);
UpdateProgress();
}
break;case WS_UPGRADE_STATE_WAIT_FOR_READY_FOR_DOWNLOAD:
if (Event == WS_UPGRADE_RESPONSE_OK)
{
m_offset = 0;
m_state = WS_UPGRADE_STATE_DATA_TRANSFER;
SendWsUpgradeCommand(WICED_OTA_UPGRADE_COMMAND_DOWNLOAD, (int)m_PatchSize);
}
break;case WS_UPGRADE_STATE_DATA_TRANSFER:
if (Event == WS_UPGRADE_RESPONSE_OK)
{
// Create thread reading unsolicited eventsif(m_bInTransfer == false) {
runOnUiThread(new Runnable() {@Override
public void run() {
m_offset = 0;
m_bInTransfer = true;
SendOTAImageData();
}
});
}
}
else if (Event == WS_UPGRADE_CONTINUE)
{
}
else if (Event == WS_UPGRADE_START_VERIFICATION)
{
m_state = WS_UPGRADE_STATE_VERIFICATION;
SendWsUpgradeCommand(WICED_OTA_UPGRADE_COMMAND_VERIFY, m_crc32);
}
else if (Event == WS_UPGRADE_ABORT)
{
Log.d(TAG, "ProcessEvent state : " + WS_UPGRADE_STATE_DATA_TRANSFER + " Event: " + WS_UPGRADE_ABORT);
m_state = WS_UPGRADE_STATE_ABORTED;
}
break;case WS_UPGRADE_STATE_VERIFICATION:
if (Event == WS_UPGRADE_RESPONSE_OK)
{
Log.d(TAG, "ProcessEvent state : " + WS_UPGRADE_STATE_VERIFICATION + " Event: " + WS_UPGRADE_RESPONSE_OK);
m_state = WS_UPGRADE_STATE_VERIFIED;
UpdateProgress();
}
else if (Event == WS_UPGRADE_RESPONSE_FAILED)
{
Log.d(TAG, "ProcessEvent state : " + WS_UPGRADE_STATE_VERIFICATION + " Event: " + WS_UPGRADE_RESPONSE_FAILED);
m_state = WS_UPGRADE_STATE_ABORTED;
UpdateProgress();
}
break;case WS_UPGRADE_STATE_ABORTED:
if (Event == WS_UPGRADE_RESPONSE_OK)
{
Log.d(TAG, "ProcessEvent state : " + WS_UPGRADE_STATE_ABORTED + " Event: " + WS_UPGRADE_RESPONSE_OK);
UpdateProgress();
}
break;default:
break;
}
}
更具体的需要您深入探究这个Android版本的ota_firwmare_upgrade的代码。通过步进调试,您便可以知道它的全部流程。
<<<<<<<<<<<<<>>>>>>>>>>>>>
Best Regards
C. L.
<<<<<<<<<<<<<>>>>>>>>>>>>>