#endif\r
\r
#ifdef ENABLE_CUSTOM_I2C\r
- custom_i2c_init(I2C_BUS_3);\r
- custom_i2c_init(I2C_BUS_0);\r
+ // custom_i2c_init(I2C_BUS_3);\r
+ // custom_i2c_init(I2C_BUS_0);\r
custom_i2c_init(I2C_BUS_2);\r
\r
#ifdef SUPORT_MAG_SERVICE\r
\r
#endif\r
start_custom_ble_service();\r
-// #ifdef SUPPORT_ALIPAY_SEC\r
-// #if !defined(A5133_DEMO_SERVER) && !defined(A5133_DEMO_CLIENT)\r
-// uapi_alipay_svr_init();\r
-// #endif\r
-// #endif\r
+#ifdef SUPPORT_ALIPAY_SEC\r
+#if !defined(A5133_DEMO_SERVER) && !defined(A5133_DEMO_CLIENT)\r
+ uapi_alipay_svr_init();\r
+#endif\r
+#endif\r
\r
#ifdef SUPPORT_A5133_SERVICE\r
uapi_a5133_service_init();\r
{\r
errcode_t result;\r
result = uapi_i2c_master_init(ALIPAY_SEC_I2C_INDEX, 100000, I2C_SPEED_MODE_SS); /* 100000: 100KHz */\r
- if (result != ERRCODE_SUCC) {\r
+ if (result != ERRCODE_SUCC && result!= ERRCODE_I2C_ALREADY_INIT) {\r
MyPrintf("se i2c init fail! ret=0x%x", result);\r
return NULL;\r
}\r
void AiVoiceModel::CancelCurAIChat(void)
{
// cancel_AI_cur_chat(); //线程发送取消当前对话
+ #ifdef SUPPORT_BLE_SERVICE
cancel_AI_cur_chat_();// 直接发送取消当前对话
+ #endif
}
int AiVoiceModel::GetAIResponseType(void)
extern "C"
{
-
-// #include "build_version.h"
-// #include "battery_hal.h"
-// extern uint8_t battery_get_voltage(float *voltage);
-// const char *get_version_string(void);
+ #ifdef SUPPORT_BLE_SERVICE
+#include "build_version.h"
+#include "battery_hal.h"
+ extern uint8_t battery_get_voltage(float *voltage);
+ const char *get_version_string(void);
+#else
extern uint8_t battery_get_voltage(float *voltage){ return 0;}
const char *get_version_string(void);
+#endif
}
${ROOT_DIR}/middleware/services/gui/uikit/utils/interfaces/kits/gfx_utils
${ROOT_DIR}/include/middleware/services/bts/br
${ROOT_DIR}/include/middleware/services/bts/common
+ ${ROOT_DIR}/zhihui/services/ble_service/transspecard/
)
set(SOURCES
#ifdef __cplusplus\r
extern "C" {\r
#endif\r
+#include "transspecard.h"\r
\r
#define HOSTENT_TIMEOUT 2000\r
#define TCP_CONNECT_TIMEOUT 2000\r
uint32_t g_tcp_fd = 0;\r
uint8_t g_netstatus = 0;\r
\r
+#define ALIPAY_TRANSSPECARD_SUPPORT_BLE 1\r
void msg_center_alipay_reply_ack(uint8_t cmd_id, uint8_t type)\r
{\r
uint8_t ack = 1; /* 与手机APK侧约定 */\r
\r
errcode_t msg_center_alipay_network_status(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len)\r
{\r
+ #if ALIPAY_TRANSSPECARD_SUPPORT_BLE\r
+ if(cmd_id != ALIPAY_TRANSSPECARD)\r
+ {\r
+ printf("msg_center_alipay_network_status cmd_id error:%d\r\n", cmd_id);\r
+ return -1;\r
+ }\r
+ g_netstatus = *((uint8_t *)usr_data);\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_alipay_network_status:netstatus = %d\r\n", g_netstatus);\r
+ return 0;\r
+ #else\r
uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data);\r
uint16_t payload_len = usr_len - tl_len;\r
uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data);\r
WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_alipay netstatus = %d\r\n", g_netstatus);\r
msg_center_alipay_reply_ack(cmd_id, type);\r
return 0;\r
+ #endif\r
}\r
\r
uint8_t msg_center_alipay_get_network_status(void)\r
\r
int msg_center_alipay_hostent_request(void *usr_data, uint16_t usr_len)\r
{\r
+ #if ALIPAY_TRANSSPECARD_SUPPORT_BLE\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "DNS域名解析请求:%s\r\n", (char *)usr_data);\r
+ int ret;\r
+ if (g_alipay_hostent_sem == NULL) {\r
+ g_alipay_hostent_sem = osSemaphoreNew(1, 0, NULL);\r
+ }\r
+ ret = send_transspecard_data(MSGCENTER_TYPE_ID_ALIPAY_HOST_INFO, (uint8_t *)usr_data, usr_len);\r
+ if (ret != 0) {\r
+ return -1;\r
+ } else {\r
+ return 0;\r
+ }\r
+ #else\r
int ret;\r
if (g_alipay_hostent_sem == NULL) {\r
g_alipay_hostent_sem = osSemaphoreNew(1, 0, NULL);\r
} else {\r
return 0;\r
}\r
+ #endif\r
}\r
\r
errcode_t msg_center_alipay_hostent_recv(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len)\r
{\r
+ #if ALIPAY_TRANSSPECARD_SUPPORT_BLE\r
+ if(cmd_id != ALIPAY_TRANSSPECARD)\r
+ {\r
+ printf("msg_center_alipay_network_status cmd_id error:%d\r\n", cmd_id);\r
+ return -1;\r
+ }\r
+ (void)memcpy_s(g_alipay_ip, IPV4_LEN, usr_data, usr_len);\r
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "接收app下发的域名解析,域名转换后的IP地址:%d.%d.%d.%d\r\n",\r
+ g_alipay_ip[0], g_alipay_ip[1], g_alipay_ip[2], g_alipay_ip[3]);\r
+ osSemaphoreRelease(g_alipay_hostent_sem);\r
+ return ERRCODE_SUCC;\r
+ #else\r
uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data);\r
uint16_t payload_len = usr_len - tl_len;\r
uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data);\r
g_alipay_ip[0], g_alipay_ip[1], g_alipay_ip[2], g_alipay_ip[3]);\r
osSemaphoreRelease(g_alipay_hostent_sem);\r
return ERRCODE_SUCC;\r
+ #endif\r
}\r
\r
int msg_center_alipay_hostent_reponse(unsigned char *ip)\r
} else {\r
ret = -1;\r
}\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "hostent wait status = 0x%x\r\n", status);\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "DNS解析 信号量获取状态 = 0x%x\r\n", status);\r
osSemaphoreDelete(g_alipay_hostent_sem);\r
g_alipay_hostent_sem = NULL;\r
return ret;\r
\r
int msg_center_alipay_connect_request(void *usr_data, uint16_t usr_len)\r
{\r
+ #if ALIPAY_TRANSSPECARD_SUPPORT_BLE\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "tcp连接请求\r\n");\r
+ int ret;\r
+ if (g_alipay_tcp_sem == NULL) {\r
+ g_alipay_tcp_sem = osSemaphoreNew(1, 0, NULL);\r
+ }\r
+ ret = send_transspecard_data(MSGCENTER_TYPE_ID_ALIPAY_CONNECT, (uint8_t *)usr_data, usr_len);\r
+ if (ret != 0) {\r
+ return -1;\r
+ } else {\r
+ return 0;\r
+ }\r
+ #else\r
int ret;\r
if (g_alipay_tcp_sem == NULL) {\r
g_alipay_tcp_sem = osSemaphoreNew(1, 0, NULL);\r
} else {\r
return 0;\r
}\r
+ #endif\r
}\r
\r
errcode_t msg_center_alipay_connect_recv(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len)\r
{\r
+ #if ALIPAY_TRANSSPECARD_SUPPORT_BLE\r
+ if(cmd_id != ALIPAY_TRANSSPECARD)\r
+ {\r
+ printf("msg_center_alipay_network_status cmd_id error:%d\r\n", cmd_id);\r
+ return -1;\r
+ }\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "接收tcp连接状态\r\n");\r
+ alipay_connect_reponse rep;\r
+ (void)memcpy_s(&rep, sizeof(alipay_connect_reponse), usr_data, usr_len);\r
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "recv alipay_connect_reponse info--> %d %d\r\n",\r
+ rep.ret, rep.fd);\r
+ g_tcp_fd = rep.fd;\r
+ osSemaphoreRelease(g_alipay_tcp_sem);\r
+ return ERRCODE_SUCC;\r
+ #else\r
uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data);\r
uint16_t payload_len = usr_len - tl_len;\r
uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data);\r
g_tcp_fd = rep.fd;\r
osSemaphoreRelease(g_alipay_tcp_sem);\r
return ERRCODE_SUCC;\r
+ #endif\r
}\r
\r
int msg_center_alipay_connect_reponse(void)\r
{\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_alipay_connect_reponse\r\n");\r
int ret;\r
osStatus_t status = osSemaphoreAcquire(g_alipay_tcp_sem, TCP_CONNECT_TIMEOUT);\r
if (status == osOK) {\r
} else {\r
ret = -1;\r
}\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "connect wait status = 0x%x\r\n", status);\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "建立TCP连接 信号量获取状态 = %x\r\n", status);\r
return ret;\r
}\r
\r
int msg_center_alipay_tcpdata_request(void *usr_data, uint16_t usr_len)\r
{\r
+ #if ALIPAY_TRANSSPECARD_SUPPORT_BLE\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "tcp数据请求 = %d\r\n",usr_len);\r
+ int ret; \r
+ ret = send_transspecard_data(MSGCENTER_TYPE_ID_ALIPAY_TCPDATA_RECV, usr_data, usr_len);\r
+ if (ret != ERRCODE_SUCC) {\r
+ return -1;\r
+ } else {\r
+ return (int)usr_len;\r
+ }\r
+ #else\r
WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "tcpdata send len = 0x%x\r\n", usr_len);\r
int ret;\r
ret = msg_center_send_data(MSGCENTER_CMD_ALIPAY, MSGCENTER_TYPE_ID_ALIPAY_TCPDATA_RECV, usr_data, usr_len);\r
} else {\r
return (int)usr_len;\r
}\r
+ #endif\r
}\r
\r
int msg_center_alipay_tcpdata_wait(uint32_t timeout)\r
{\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "msg_center_alipay_tcpdata_wait = %d\r\n",timeout);\r
int ret;\r
osStatus_t status = osSemaphoreAcquire(g_alipay_tcp_sem, timeout);\r
if (status == osOK) {\r
} else {\r
ret = 0;\r
}\r
- WEARABLE_LOGD(WEARABLE_LOG_MODULE_MSG_CENTER, "tcpdata wait status = 0x%x\r\n", status);\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "请求TCP数据 信号量获取状态 0x%x\r\n", status);\r
return ret;\r
}\r
\r
errcode_t msg_center_alipay_tcpdata_recv(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len)\r
{\r
+ #if ALIPAY_TRANSSPECARD_SUPPORT_BLE\r
+ if(cmd_id != ALIPAY_TRANSSPECARD)\r
+ {\r
+ printf("msg_center_alipay_network_status cmd_id error:%d\r\n", cmd_id);\r
+ return -1;\r
+ }\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "接收tcp数据:%d\r\n",usr_len);\r
+ if (g_tcp_data != NULL) {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER,\r
+ "The last buff hasn't been read yet, current payload len is %u.\r\n", usr_len);\r
+ return ERRCODE_FAIL;\r
+ }\r
+ g_tcp_data = (uint8_t *)malloc(usr_len);\r
+ if (g_tcp_data != NULL) {\r
+ g_tcp_data_len = usr_len;\r
+ (void)memcpy_s(g_tcp_data, g_tcp_data_len, usr_data, usr_len);\r
+ }\r
+\r
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "recv tcpdata len = %d\r\n",\r
+ g_tcp_data_len);\r
+ osSemaphoreRelease(g_alipay_tcp_sem);\r
+ return ERRCODE_SUCC;\r
+ #else\r
uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data);\r
uint16_t payload_len = usr_len - tl_len;\r
uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data);\r
g_tcp_data_len);\r
osSemaphoreRelease(g_alipay_tcp_sem);\r
return ERRCODE_SUCC;\r
+ #endif\r
}\r
\r
+//接受数据\r
int msg_center_alipay_tcpdata_read(void *mem, int len)\r
{\r
+ #if ALIPAY_TRANSSPECARD_SUPPORT_BLE\r
+ int ret = 0;\r
+ // printf("进入 msg_center_alipay_tcpdata_read 函数,请求读取的长度为: %d\n", len);\r
+\r
+ if (g_tcp_data != NULL) {\r
+ // printf("g_tcp_data 不为 NULL,准备读取数据\n");\r
+ int read_len = min(len, g_tcp_data_len);\r
+ // printf("实际可读取的长度为: %d\n", read_len);\r
+\r
+ (void)memcpy_s(mem, len, g_tcp_data + g_tcp_data_readed, read_len);\r
+ // printf("已将 %d 字节的数据从 g_tcp_data 复制到 mem\n", read_len);\r
+\r
+ g_tcp_data_readed += read_len;\r
+ g_tcp_data_len -= read_len;\r
+ // printf("更新后,已读取的数据长度为: %d,剩余数据长度为: %d\n", g_tcp_data_readed, g_tcp_data_len);\r
+\r
+ ret = read_len;\r
+\r
+ if (g_tcp_data_len == 0) {\r
+ // printf("数据已全部读取,释放 g_tcp_data 内存\n");\r
+ free(g_tcp_data);\r
+ g_tcp_data = NULL;\r
+ g_tcp_data_readed = 0;\r
+ // printf("g_tcp_data 已置为 NULL,已读取数据长度重置为 0\n");\r
+ }\r
+ } else {\r
+ ret = -2; // no data for read\r
+ // printf("g_tcp_data 为 NULL,没有数据可供读取,返回 -2\n");\r
+ }\r
+ // printf("离开 msg_center_alipay_tcpdata_read 函数,实际读取的长度为: %d\n", ret);\r
+ return ret;\r
+ #else\r
int ret = 0;\r
if (g_tcp_data != NULL) {\r
int read_len = min(len, g_tcp_data_len);\r
}\r
WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "read tcpdata len = (%d, %d)\r\n", len, ret);\r
return ret;\r
+ #endif\r
}\r
\r
int msg_center_alipay_close_request(void)\r
{\r
+ #if ALIPAY_TRANSSPECARD_SUPPORT_BLE\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_MSG_CENTER, "发送socket关闭请求\r\n");\r
+ if (g_alipay_tcp_sem != NULL) {\r
+ osSemaphoreDelete(g_alipay_tcp_sem);\r
+ g_alipay_tcp_sem = NULL;\r
+ }\r
+ if (g_tcp_data != NULL) {\r
+ WEARABLE_LOGI(WEARABLE_LOG_MODULE_MSG_CENTER, "need free data buff.\r\n");\r
+ free(g_tcp_data);\r
+ g_tcp_data = NULL;\r
+ g_tcp_data_readed = 0;\r
+ }\r
+ int ret;\r
+ int send_ret = send_transspecard_data(MSGCENTER_TYPE_ID_ALIPAY_CLOSE, &g_tcp_fd, sizeof(g_tcp_fd));\r
+ if (send_ret != ERRCODE_SUCC) {\r
+ ret = -1;\r
+ } else {\r
+ ret = 0;\r
+ }\r
+ g_tcp_fd = 0;\r
+ return ret;\r
+ #else\r
if (g_alipay_tcp_sem != NULL) {\r
osSemaphoreDelete(g_alipay_tcp_sem);\r
g_alipay_tcp_sem = NULL;\r
}\r
g_tcp_fd = 0;\r
return ret;\r
+ #endif\r
}\r
\r
errcode_t msg_center_alipay_close(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len)\r
{\r
+ #if ALIPAY_TRANSSPECARD_SUPPORT_BLE\r
+ if(cmd_id != ALIPAY_TRANSSPECARD)\r
+ {\r
+ printf("msg_center_alipay_close cmd_id error:%d,ecpected cmd_id is:0x09\r\n", cmd_id);\r
+ return -1;\r
+ }\r
+ return ERRCODE_SUCC;\r
+ #else\r
uint8_t tl_len = msg_center_get_tlv_tl_len(usr_data);\r
uint16_t payload_len = usr_len - tl_len;\r
uint8_t *tlv_payload = (uint8_t *)msg_center_get_tlv_payload(usr_data);\r
\r
return ERRCODE_SUCC;\r
+ #endif\r
}\r
\r
errcode_t msg_center_alipay_time_sync(uint8_t cmd_id, uint8_t type, void *usr_data, uint16_t usr_len)\r
"batterry_service",
"bleservice",
"blemoder",
- # "factorytest_service",
+ "transspecard",
+ "factorytest_service",
# "hid_service",
# "producttest",
"ppg_hal",
{HAL_CLOCKS_APP_UART_H1_CLK, TURN_ON}, // uart h1 clock\r
{HAL_CLOCKS_APP_I2C0_CLK, TURN_OFF}, // i2c0 clock\r
{HAL_CLOCKS_APP_I2C1_CLK, TURN_ON}, // i2c1 clock\r
- {HAL_CLOCKS_APP_I2C2_CLK, TURN_OFF}, // i2c2 clock\r
+ {HAL_CLOCKS_APP_I2C2_CLK, TURN_ON}, // i2c2 clock\r
{HAL_CLOCKS_APP_I2C3_CLK, TURN_ON}, // i2c3 clock\r
{HAL_CLOCKS_APP_QSPI_1CS_CLK, TURN_ON}, // qspi clock\r
{HAL_CLOCKS_APP_XIP_BUS_CLK, TURN_ON}, // xip bus clock\r
/* ------------------------------- AI录音数据上传接口 ------------------------------- */
#define AI_RECORD_TEST 0 //若需要调试可以打开该宏
+#ifdef SUPPORT_BLE_SERVICE
#include "bleService.h"
static uint32_t AI_audio_size=0;
static uint8_t Cur_AI_Model= 0;
g_audioSourceProcessInput.bThreadRun = false;
return -1;
}
+#endif
+
#ifdef __cplusplus
};
#endif
+add_subdirectory_if_exist(transspecard)
add_subdirectory_if_exist(bleservice)
add_subdirectory_if_exist(blemoder)
--- /dev/null
+
+set(COMPONENT_NAME "transspecard")
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}
+
+)
+
+set(PRIVATE_HEADER
+ ${ROOT_DIR}/protocol/bt/host/bt/bts/bt_sample/ble_profile/profiles/include
+ ${ROOT_DIR}/protocol/bt/host/bt/bts/bg_common/include/sdk_common
+ ${ROOT_DIR}/protocol/bt/host/bt/bts/host/inc
+ ${ROOT_DIR}/protocol/bt/host/bt/bts/bg_common/include
+ ${ROOT_DIR}/protocol/bt/host/bt/bts/bg_common/include/log
+ ${ROOT_DIR}/protocol/bt/host/bt/bts/bg_common/include/gdk_common
+
+ ${ROOT_DIR}/zhihui/services/ble_service/bleservice
+ ${ROOT_DIR}/application/wearable/fd230/service/alipay_msg/
+)
+
+
+if("FD230" IN_LIST DEFINES)
+set(PRIVATE_HEADER
+ ${PRIVATE_HEADER}
+ ${ROOT_DIR}/application/wearable/fd230/nativeapp/nativeui/bluetooth/include
+ ${ROOT_DIR}/application/wearable/fd230/CustomUIComponentTool/uicomponents
+ ${ROOT_DIR}/application/wearable/fd230/nativeapp/nativeui
+ ${ROOT_DIR}/application/wearable/fd230/nativeapp/nativelauncher/include
+ ${ROOT_DIR}/application/wearable/fd230/nativeapp/nativeui/screennotify/include
+ ${ROOT_DIR}/application/wearable/fd230/service/broadcast/include
+)
+else()
+set(PRIVATE_HEADER
+ ${PRIVATE_HEADER}
+ ${ROOT_DIR}/application/wearable/nativeapp/nativeui/bluetooth/include
+ ${ROOT_DIR}/application/wearable/fd230/CustomUIComponentTool/uicomponents
+ ${ROOT_DIR}/application/wearable/nativeapp/nativeui
+ ${ROOT_DIR}/application/wearable/nativeapp/nativelauncher/include
+ ${ROOT_DIR}/application/wearable/nativeapp/nativeui/screennotify/include
+ )
+endif()
+if("FD230" IN_LIST DEFINES)
+set(SOURCES
+ ${CMAKE_CURRENT_SOURCE_DIR}/transspecard.c
+)
+else()
+set(SOURCES
+
+)
+
+endif()
+
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+# -std=c++11
+-Wno-error
+-Wno-unused-parameter
+-fno-exceptions
+-fno-unwind-tables
+-fno-asynchronous-unwind-tables
+-Wno-undef
+-Wno-bitwise-op-parentheses
+-Wno-shift-op-parentheses
+-nostdlibinc
+-nostdinc
+-nostdlib
+-Wno-c++11-narrowing
+-Wno-error=unused-function
+)
+
+set(WHOLE_LINK
+ true
+)
+
+set(MAIN_COMPONENT
+ false
+)
+
+set(PUBLIC_DEFINES
+ CUSTOM_HID_SERVICE
+)
+
+set(PRIVATE_DEFINES
+
+)
+
+build_component()
+
--- /dev/null
+#include "transspecard.h"
+#include <soc_osal.h>
+#include "wearable_log.h"
+#include "bleService.h"
+#include <errcode.h>
+#include "alipay_app.h"
+#include "factorytestService.h"
+#include <time.h>
+#include <cmsis_os2.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#define alipay_transspecard_log 0 // 用于日志打印
+#define ALIPAY_TRANSSPECARD_ERRCODE_SUCC 0
+#define ALIPAY_TRANSSPECARD_ERRCODE_FAIL -1
+#define MAX_RETRY_TIMES 3 // 重传次数
+#define PACKET_INTERVAL_TIMEOUT 1000 // 数据包间隔超时时间,单位:ms
+#define PACKET_DELTA_TIMEOUT 70 // 数据包时间差超时时间,单位:ms
+#define PACKET_HEAD_AND_TAIL_LEN 18 // 数据包头部和尾部的长度
+
+static const transspecard_pkt_recv_info_t g_transspecard_alipay_sec_tbl[] = {
+ {ALIPAY_TRANSSPECARD, TRANSSPECARD_TYPE_ID_ALIPAY_NETWORK_STATUS, msg_center_alipay_network_status},
+ {ALIPAY_TRANSSPECARD, TRANSSPECARD_TYPE_ID_ALIPAY_HOST_INFO, msg_center_alipay_hostent_recv},
+ {ALIPAY_TRANSSPECARD, TRANSSPECARD_TYPE_ID_ALIPAY_CONNECT, msg_center_alipay_connect_recv},
+ {ALIPAY_TRANSSPECARD, TRANSSPECARD_TYPE_ID_ALIPAY_TCPDATA_RECV, msg_center_alipay_tcpdata_recv},
+ {ALIPAY_TRANSSPECARD, TRANSSPECARD_TYPE_ID_ALIPAY_CLOSE, msg_center_alipay_close},
+ {ALIPAY_TRANSSPECARD, TRANSSPECARD_TYPE_ID_ALIPAY_TIME_SYNC, msg_center_alipay_time_sync},
+ {ALIPAY_TRANSSPECARD, TRANSSPECARD_TYPE_ID_ALIPAY_ACK, msg_center_alipay_receive_ack},
+};
+
+static uint8_t alipay_transspecard_sec_type_dispatch(uint8_t type_id, uint8_t type, void *usr_data, uint16_t usr_len)
+{
+ uint8_t tbl_size = sizeof(g_transspecard_alipay_sec_tbl) / sizeof(g_transspecard_alipay_sec_tbl[0]);
+ uint8_t i;
+ for (i = 0; i < tbl_size; i++)
+ {
+ transspecard_pkt_recv_info_t *item = (transspecard_pkt_recv_info_t *)&g_transspecard_alipay_sec_tbl[i];
+ if ((item->type_id == type_id) && (item->type == type) && (item->recv_hook != NULL))
+ {
+ item->recv_hook(type_id, type, usr_data, usr_len);
+ return ALIPAY_TRANSSPECARD_ERRCODE_SUCC;
+ }
+ }
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+}
+
+/**
+ * 计算crc时的求和函数,可以递归,从而实现多段数据的组合计算
+ */
+static uint8_t calculate_lrc_transspecard(uint8_t *data, uint16_t len, uint8_t _lrcValue)
+{
+ uint8_t lrcValue = _lrcValue;
+ if (data == NULL)
+ {
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+ for (uint16_t i = 0; i < len; i++)
+ {
+ lrcValue = lrcValue + data[i];
+ }
+ return lrcValue;
+}
+
+static uint8_t get_crc_from_lrc_transspecard(uint8_t lrcValue)
+{
+ uint8_t crcbuf = 0;
+ crcbuf = lrcValue % 256;
+ crcbuf = 256 - crcbuf;
+ crcbuf = crcbuf % 256;
+ return crcbuf;
+}
+
+static uint8_t calculate_CRC_transspecard(uint8_t *data, uint16_t len) // 计算
+{
+ uint8_t crcbuf = 0;
+ uint8_t lrcValue = 0x00;
+ lrcValue = calculate_lrc_transspecard(data + 17, len - 17, 0x00);
+ crcbuf = get_crc_from_lrc_transspecard(lrcValue);
+ return crcbuf;
+}
+
+// 设置乘车码消息类型ID
+static uint8_t set_alipay_transspecard_type_Id(uint8_t type)
+{
+ uint8_t type_id = 0;
+ switch (type)
+ {
+ case 1:
+ type_id = 0x01;
+ break;
+ case 2:
+ type_id = 0x02;
+ break;
+ case 3:
+ type_id = 0x03;
+ break;
+ case 4:
+ type_id = 0x04;
+ break;
+ case 5:
+ type_id = 0x05;
+ break;
+ case 0xff:
+ type_id = 0xff;
+ default:
+ printf("set_alipay_transspecard_type_Id error,%d\r\n", type);
+ type_id = 0xff;
+ break;
+ }
+ return type_id;
+}
+
+// 获取阿里的ble_nus最大数据长度
+static uint16_t get_alipay_ble_nus_max_data_len(void)
+{
+ uint16_t alipay_ble_nus_max_data_len = 0;
+ if (ble_nus_max_data_len > 512)
+ {
+ alipay_ble_nus_max_data_len = 512;
+ }
+ else
+ {
+ alipay_ble_nus_max_data_len = ble_nus_max_data_len;
+ }
+ return alipay_ble_nus_max_data_len;
+}
+static uint8_t ble_transspecard_receive_ack_id = 0xff;
+static osSemaphoreId_t g_transspecard_ack_sem = NULL; // 全局信号量
+static uint8_t send_retry_count = 0;
+
+errcode_t msg_center_alipay_receive_ack(uint8_t type_id, uint8_t type, void *usr_data, uint16_t usr_len)
+{
+ uint8_t *data = (uint8_t *)usr_data;
+ if (data == NULL)
+ {
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+ printf("msg_center_alipay_receive_ack: %d\n", data[0]);
+ ble_transspecard_receive_ack_id = data[0];
+ if (g_transspecard_ack_sem != NULL)
+ {
+ osSemaphoreRelease(g_transspecard_ack_sem); // 有重传请求,释放信号量触发重传
+ }
+ return ALIPAY_TRANSSPECARD_ERRCODE_SUCC;
+}
+
+uint8_t ble_transspecard_receive_ack(void)
+{
+ return ble_transspecard_receive_ack_id;
+}
+
+// 组装数据包的函数
+static uint8_t *assemble_packet(uint8_t type_id, uint8_t packet_id, uint8_t send_packet_total, uint16_t datalen, uint16_t current_datalen, void *data)
+{
+ uint8_t *buf = (uint8_t *)malloc(17 + current_datalen + 1);
+ if (buf == NULL)
+ {
+ printf("malloc buf failed!\r\n");
+ return NULL;
+ }
+
+#if alipay_transspecard_log
+ printf("为第 %u 个分包分配内存,大小为: %u 字节\n", packet_id, 17 + current_datalen + 1);
+#endif
+
+ memset(buf, 0, 17 + current_datalen + 1);
+
+ // 设置消息头部信息
+ buf[0] = 0x72; // 消息头
+ buf[1] = 0x09; // 类型 :0x09 代表支付宝乘车码
+ buf[2] = set_alipay_transspecard_type_Id(type_id); // 类型ID
+ memcpy(buf + 3, &send_packet_total, 4); // 总包数
+ memcpy(buf + 7, &datalen, 4); // 总数据长度
+ memcpy(buf + 11, &packet_id, 4); // 数据包ID,从1开始递增
+ memcpy(buf + 15, ¤t_datalen, 2); // 包数据长度
+
+ // 处理数据和计算CRC
+ if (data == NULL)
+ {
+ // 数据为空 按照18个字节总长度发送给app
+ buf[17] = 0x00; // 直接写0x00的校验和
+ }
+ else
+ {
+ // 数据不为空
+ memcpy(buf + 17, data + (packet_id - 1) * (get_alipay_ble_nus_max_data_len() - PACKET_HEAD_AND_TAIL_LEN), current_datalen); // 拷贝当前段数据到buf+17的位置
+ buf[17 + current_datalen] = calculate_CRC_transspecard(buf, 17 + current_datalen); // 计算CRC校验码
+ }
+
+#if alipay_transspecard_log
+ printf("第 %u 个分包的CRC校验码: 0x%02x\n", packet_id, buf[17 + current_datalen]);
+ printf("打印组装的数据:\r\n");
+ for (int j = 0; j < 17 + current_datalen + 1; j++)
+ {
+ printf("%02x ", buf[j]);
+ }
+ printf("\r\n");
+#endif
+
+ return buf;
+}
+
+// 发送指定范围的数据包
+static uint8_t send_packets_range(uint8_t type_id, void *data, uint16_t datalen, uint8_t start_packet, uint8_t send_packet_total)
+{
+ uint32_t singlebuflen = (get_alipay_ble_nus_max_data_len() - PACKET_HEAD_AND_TAIL_LEN);
+ uint8_t current_packet = start_packet;
+
+ while (current_packet <= send_packet_total)
+ {
+ uint16_t current_datalen = (current_packet == send_packet_total) ? (datalen % singlebuflen) : singlebuflen;
+ uint8_t *buf = assemble_packet(type_id, current_packet, send_packet_total, datalen, current_datalen, data);
+ if (buf == NULL)
+ {
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+ // 发送数据
+ ble_factorytest_server_send_ota_report(buf, 17 + current_datalen + 1);
+ printf("发送第 %u 个分包(总 %u 包)\n", current_packet, send_packet_total);
+ msleep(PACKET_DELTA_TIMEOUT); // 增加延时,确保可以成功发送成功
+
+ // 释放内存
+ free(buf);
+ buf = NULL;
+ current_packet++;
+ }
+
+ return ALIPAY_TRANSSPECARD_ERRCODE_SUCC;
+}
+// 发送数据的函数,支持分包发送
+uint8_t send_transspecard_data(uint8_t type_id, void *data, uint16_t datalen)
+{
+ uint32_t singlebuflen = (get_alipay_ble_nus_max_data_len() - PACKET_HEAD_AND_TAIL_LEN);
+ // 计算分包数量,即总包数
+ uint8_t send_packet_total = datalen / singlebuflen;
+ if (datalen % singlebuflen != 0)
+ {
+ send_packet_total++;
+ }
+
+ printf("总数据长度: %u 字节, 预计分包数量: %u 个\n", datalen, send_packet_total);
+
+ // 单包传输逻辑
+ if (send_packet_total == 1)
+ {
+ uint16_t current_datalen = datalen;
+ uint8_t *buf = assemble_packet(type_id, 1, send_packet_total, datalen, current_datalen, data);
+ if (buf == NULL)
+ {
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL; // 假设ALIPAY_TRANSSPECARD_ERRCODE_FAIL为1
+ }
+
+ // 发送数据
+ ble_factorytest_server_send_ota_report(buf, 17 + current_datalen + 1);
+ // printf("发送第 1 个分包(总 1 包)\n");
+ msleep(PACKET_DELTA_TIMEOUT); // 增加延时,确保可以成功发送成功
+
+ // 释放内存
+ free(buf);
+ buf = NULL;
+ return ALIPAY_TRANSSPECARD_ERRCODE_SUCC;
+ }
+
+ // 多包传输逻辑
+ uint8_t current_packet = 1;
+ int all_packets_sent = 0;
+ // 初始化信号量
+ if (g_transspecard_ack_sem == NULL)
+ {
+ g_transspecard_ack_sem = osSemaphoreNew(1, 0, NULL);
+ }
+
+ // 先顺序发送所有数据包
+ if (send_packets_range(type_id, data, datalen, 1, send_packet_total) == ALIPAY_TRANSSPECARD_ERRCODE_FAIL)
+ {
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+ send_retry_count = 0;
+ while (send_retry_count < MAX_RETRY_TIMES)
+ {
+ osStatus_t status = osSemaphoreAcquire(g_transspecard_ack_sem, PACKET_INTERVAL_TIMEOUT); // 等待信号量,直到有重传请求或全部接收成功
+ if (status == osOK)
+ {
+ uint8_t ack_id = ble_transspecard_receive_ack();
+ if (ack_id > 0 && ack_id <= send_packet_total)
+ {
+ // send_retry_count = 0;
+ printf("收到重传请求,从第 %u 个分包开始重新发送\n", ack_id);
+ // 调用函数重传指定范围的数据包
+ if (send_packets_range(type_id, data, datalen, ack_id, send_packet_total) == ALIPAY_TRANSSPECARD_ERRCODE_FAIL)
+ {
+ printf("重传失败\n");
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+ }
+ else if (ack_id == 0)
+ {
+ printf("对方全部收到,进行下一步操作\n");
+ break;
+ }
+ }
+ else
+ {
+ printf("信号量获取失败\n");
+ send_retry_count++;
+ msleep(PACKET_INTERVAL_TIMEOUT); // 每秒检查一次
+ continue;
+ }
+ }
+
+ // 发送完成后删除信号量
+ osSemaphoreDelete(g_transspecard_ack_sem);
+ g_transspecard_ack_sem = NULL;
+
+ return ALIPAY_TRANSSPECARD_ERRCODE_SUCC;
+}
+
+#if 0
+uint8_t send_transspecard_data(uint8_t type_id, void *data, uint16_t datalen)
+{
+ uint32_t singlebuflen = ble_nus_max_data_len - 20;
+ // uint32_t singlebuflen = 100; //测试用
+ // 计算分包数量,即总包数
+ uint8_t send_packet_total = datalen / singlebuflen;
+ if (datalen % singlebuflen != 0)
+ {
+ send_packet_total++;
+ }
+
+#if alipay_transspecard_log
+ printf("总数据长度: %u 字节, 预计分包数量: %u 个\n", datalen, send_packet_total);
+#endif
+
+ uint8_t current_packet = 1;
+ ble_transspecard_receive_ack_id = 0xff;
+ while (current_packet <= send_packet_total)
+ {
+ uint16_t current_datalen = (current_packet == send_packet_total) ? (datalen % singlebuflen) : singlebuflen;
+ uint8_t *buf = (uint8_t *)malloc(17 + current_datalen + 1);
+ if (buf == NULL)
+ {
+ printf("malloc buf failed!\r\n");
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+#if alipay_transspecard_log
+ printf("为第 %u 个分包分配内存,大小为: %u 字节\n", current_packet, 17 + current_datalen + 1);
+#endif
+
+ memset(buf, 0, 17 + current_datalen + 1);
+
+ uint8_t packet_id = current_packet;
+ // 设置消息头部信息
+ buf[0] = 0x72; // 消息头
+ buf[1] = 0x09; // 类型 :0x09 代表支付宝乘车码
+ buf[2] = set_alipay_transspecard_type_Id(type_id); // 类型ID
+ memcpy(buf + 3, &send_packet_total, 4); // 总包数
+ memcpy(buf + 7, &datalen, 4); // 总数据长度
+ memcpy(buf + 11, &packet_id, 4); // 数据包ID,从1开始递增
+ memcpy(buf + 15, ¤t_datalen, 2); // 包数据长度
+
+ // 处理数据和计算CRC
+ if (data == NULL)
+ {
+ // 数据为空 按照18个字节总长度发送给app
+ buf[17] = 0x00; // 直接写0x00的校验和
+ }
+ else
+ {
+ // 数据不为空
+ memcpy(buf + 17, data + (current_packet - 1) * singlebuflen, current_datalen); // 拷贝当前段数据到buf+17的位置
+ buf[17 + current_datalen] = calculate_CRC_transspecard(buf, 17 + current_datalen); // 计算CRC校验码
+ }
+
+#if alipay_transspecard_log
+ printf("第 %u 个分包的CRC校验码: 0x%02x\n", current_packet, buf[17 + current_datalen]);
+ printf("打印组装的数据:\r\n");
+ for (int j = 0; j < 17 + current_datalen + 1; j++)
+ {
+ printf("%02x ", buf[j]);
+ }
+ printf("\r\n");
+#endif
+
+ // 发送数据
+ ble_factorytest_server_send_ota_report(buf, 17 + current_datalen + 1);
+ printf("发送第 %u 个分包(总 %u 包)\n", packet_id, send_packet_total);
+ msleep(PACKET_DELTA_TIMEOUT); // 增加延时,确保可以成功发送成功
+
+ if (0)
+ {
+#if alipay_transspecard_log
+ printf("支持分包传输,等待确认\n");
+#endif
+ send_retry_count = 0;
+ uint8_t ack;
+ while (send_retry_count < MAX_RETRY_TIMES)
+ {
+#if alipay_transspecard_log
+ printf("等待第 %u 个分包的确认\n", packet_id);
+#endif
+ msleep(PACKET_INTERVAL_TIMEOUT); // 每秒检查一次
+ ack = ble_transspecard_receive_ack();
+ if (ack == 0)
+ {
+#if alipay_transspecard_log
+ printf("第 %u 个分包收到确认\n", packet_id);
+#endif
+ // 对方收到了,发送下一包
+ free(buf);
+ buf = NULL;
+ current_packet++;
+ break;
+ }
+ else if (ack > 0 && ack <= send_packet_total)
+ {
+#if alipay_transspecard_log
+ printf("收到重传请求,重传第 %u 个分包\n", ack);
+#endif
+ // 从指定的包开始重新发送
+ free(buf);
+ buf = NULL;
+ current_packet = ack;
+ break;
+ }
+ else
+ {
+ // 未收到确认,重试
+ send_retry_count++;
+#if alipay_transspecard_log
+ printf("第 %u 个分包未收到确认,重试第 %u 次\n", packet_id, send_retry_count);
+#endif
+ ble_factorytest_server_send_ota_report(buf, 17 + current_datalen + 1);
+ msleep(PACKET_DELTA_TIMEOUT); // 增加延时,确保可以成功发送成功
+ }
+ }
+
+ if (send_retry_count >= MAX_RETRY_TIMES)
+ {
+#if alipay_transspecard_log
+ printf("第 %u 个分包发送失败,达到最大重试次数\n", packet_id);
+#endif
+ free(buf);
+ buf = NULL;
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+ }
+ else
+ {
+#if alipay_transspecard_log
+ printf("不支持分包传输,等待确认\n");
+#endif
+ // 释放内存
+ free(buf);
+ buf = NULL;
+ current_packet++;
+ }
+ }
+
+ return ALIPAY_TRANSSPECARD_ERRCODE_SUCC;
+}
+#endif
+
+// 接收缓冲区最大长度
+#define MAX_RECEIVE_BUFFER_SIZE (1024 * 4) //
+#define RECEIVE_PACKET_FIRST 0x01 // 第一个包
+#define RECEVIE_PACKET_COMPLETED_ACK 0x00 // 最后一个包接收完成ACK
+#define RECEIVE_PACKET_HEADER 0x73 // 消息头
+#define RECEIVE_PACKET_TYPE 0x09 // 类型 :0x09 代表支付宝乘车码
+// 全局变量,用于存储接收状态
+static uint8_t receive_packet_total = 0;
+static uint16_t receive_total_datalen = 0;
+static uint8_t *packet_received_flags = NULL;
+static uint8_t *receive_buffer = NULL;
+static uint8_t expected_packet_id = 1;
+static uint8_t receive_retry_count = 0;
+static osTimerId_t ble_transspecard_receive_timer = NULL; // 接收定时器
+static uint8_t isProcessingData = 0; // 全局标志,指示是否正在处理数据
+
+// 封装通知发送方重发的函数
+static void notify_resend(uint8_t packet_id)
+{
+ if (receive_packet_total <= 1)
+ {
+ printf("只有一个包,无需重传\n");
+ return;
+ }
+ // 发送重传请求
+ uint8_t *retransmit_req = (uint8_t *)malloc(19);
+ if (retransmit_req == NULL)
+ {
+ printf("malloc retransmit_req failed!\r\n");
+ return;
+ }
+ uint32_t temp_32 = 1;
+ retransmit_req[0] = 0x72; // 消息头
+ retransmit_req[1] = 0x09; // 类型 :0x09 代表支付宝乘车码
+ retransmit_req[2] = 0xFF; // 重传请求类型ID
+ memcpy(retransmit_req + 3, &temp_32, 4); // 总包数
+ memcpy(retransmit_req + 7, &temp_32, 4); // 总数据长度
+ memcpy(retransmit_req + 11, &temp_32, 4); // 数据包ID,从1开始递增
+ memcpy(retransmit_req + 15, &temp_32, 2); // 包数据长度
+ retransmit_req[17] = packet_id;
+ retransmit_req[18] = calculate_CRC_transspecard(retransmit_req, 18); // 计算CRC校验码
+ ble_factorytest_server_send_ota_report(retransmit_req, 19);
+ msleep(PACKET_DELTA_TIMEOUT); // 增加延时,确保可以成功发送成功
+
+ free(retransmit_req);
+ retransmit_req = NULL;
+ return;
+}
+
+// 释放动态分配的内存
+static void ble_transspecard_receive_cleanup_resources()
+{
+ if (packet_received_flags != NULL)
+ {
+ free(packet_received_flags);
+ packet_received_flags = NULL;
+ }
+ if (receive_buffer != NULL)
+ {
+ free(receive_buffer);
+ receive_buffer = NULL;
+ }
+ receive_packet_total = 0;
+ receive_total_datalen = 0;
+ return;
+}
+
+// 接收定时器回调函数
+static void ble_transspecard_receive_timer_CallBack(void *arg)
+{
+ printf("等待第 %u 个数据包超时,请求重传重传次数:%d\n", expected_packet_id, receive_retry_count);
+ receive_retry_count++;
+ if (receive_retry_count >= MAX_RETRY_TIMES)
+ {
+ printf("第 %u 个数据包接收失败,达到最大重试次数\n", expected_packet_id);
+ // 释放动态分配的内存
+ ble_transspecard_receive_cleanup_resources();
+ // 停止并删除定时器
+ if (ble_transspecard_receive_timer != NULL)
+ {
+ osTimerStop(ble_transspecard_receive_timer);
+ osTimerDelete(ble_transspecard_receive_timer);
+ ble_transspecard_receive_timer = NULL;
+ }
+ receive_retry_count = 0;
+ // 通知发送方重新从第一包开始发送
+ notify_resend(RECEIVE_PACKET_FIRST);
+ return;
+ }
+ // 发送重传请求
+ notify_resend(expected_packet_id);
+}
+
+// 封装解析数据的函数
+uint8_t parse_transspecard_data(void *buf, uint16_t event_size)
+{
+ if (isProcessingData)
+ {
+ printf("Already processing data, discarding new data!\n");
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+ isProcessingData = 1;
+
+#if alipay_transspecard_log
+ printf("parse_transspecard_data len:%d\r\n", event_size);
+#endif
+ // 检查数据包长度是否小于17字节
+ if (event_size < 17)
+ {
+ printf("received packet length is too short!\r\n");
+ isProcessingData = 0;
+ ble_transspecard_receive_cleanup_resources(); // 释放动态分配的内存
+ notify_resend(RECEIVE_PACKET_FIRST); // 通知发送方重新从第一包开始发送
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+ // 解析消息头部信息
+ uint8_t message_header = *(uint8_t *)buf;
+ uint8_t message_type = *(uint8_t *)(buf + 1);
+ uint8_t type_id = *(uint8_t *)(buf + 2);
+ uint32_t current_packet_total = *(uint32_t *)(buf + 3);
+ uint32_t current_total_datalen = *(uint32_t *)(buf + 7);
+ uint32_t current_packet_id = *(uint32_t *)(buf + 11);
+ uint16_t current_datalen = *(uint16_t *)(buf + 15);
+
+#if alipay_transspecard_log
+ // 打印头部信息
+ printf("Message Header: 0x%02X\n", message_header);
+ printf("Message Type: 0x%02X\n", message_type);
+ printf("Type ID: 0x%02X\n", type_id);
+ printf("Current Packet Total: %u\n", current_packet_total);
+ printf("Current Total Data Length: %u\n", current_total_datalen);
+ printf("Current Packet ID: %u\n", current_packet_id);
+ printf("Current Data Length: %u\n", current_datalen);
+#endif
+
+ // 检查消息头和类型
+ if (message_header != RECEIVE_PACKET_HEADER || message_type != RECEIVE_PACKET_TYPE)
+ {
+ printf("Invalid message header or type!\r\n");
+ isProcessingData = 0;
+ ble_transspecard_receive_cleanup_resources();
+ notify_resend(RECEIVE_PACKET_FIRST);
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+ if (receive_packet_total == 0)
+ {
+ // 首次接收到数据包,检查是否从第一包开始
+ if (current_packet_id != 1)
+ {
+ printf("Did not receive the first packet! Expected 1, but got %u.\r\n", current_packet_id);
+ isProcessingData = 0;
+ ble_transspecard_receive_cleanup_resources();
+ notify_resend(RECEIVE_PACKET_FIRST);
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+ // 首次接收到数据包,初始化相关信息
+ receive_packet_total = current_packet_total;
+ receive_total_datalen = current_total_datalen;
+
+ if (receive_total_datalen > MAX_RECEIVE_BUFFER_SIZE)
+ {
+ printf("Received data length exceeds buffer size!\r\n");
+ isProcessingData = 0;
+ ble_transspecard_receive_cleanup_resources();
+ notify_resend(RECEIVE_PACKET_FIRST);
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+ packet_received_flags = (uint8_t *)malloc(receive_packet_total);
+ if (packet_received_flags == NULL)
+ {
+ printf("malloc packet received flags failed!\r\n");
+ isProcessingData = 0;
+ ble_transspecard_receive_cleanup_resources();
+ notify_resend(RECEIVE_PACKET_FIRST);
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+ memset(packet_received_flags, 0, receive_packet_total);
+
+ receive_buffer = (uint8_t *)malloc(receive_total_datalen);
+ if (receive_buffer == NULL)
+ {
+ printf("malloc receive buffer failed!\r\n");
+ isProcessingData = 0;
+ ble_transspecard_receive_cleanup_resources();
+ notify_resend(RECEIVE_PACKET_FIRST);
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+ memset(receive_buffer, 0, receive_total_datalen);
+
+ expected_packet_id = 1;
+ }
+
+ if (current_packet_id < 1 || current_packet_id > receive_packet_total)
+ {
+ printf("invalid packet id: %u!\r\n", current_packet_id);
+ isProcessingData = 0;
+ ble_transspecard_receive_cleanup_resources();
+ notify_resend(RECEIVE_PACKET_FIRST);
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+ // 检查是否按顺序接收
+ if (current_packet_id != expected_packet_id)
+ {
+ printf("Received packet out of order! Expected %u, but got %u.\r\n", expected_packet_id, current_packet_id);
+ isProcessingData = 0;
+ notify_resend(expected_packet_id);
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+ if (packet_received_flags[current_packet_id - 1])
+ {
+ // 该数据包已经接收过,忽略
+ printf("Packet %u has already been received, ignoring.\n", current_packet_id);
+ isProcessingData = 0;
+ return ALIPAY_TRANSSPECARD_ERRCODE_SUCC;
+ }
+
+ // 检查 CRC 校验码
+ uint8_t calculated_crc = calculate_CRC_transspecard(buf, 17 + current_datalen);
+ uint8_t received_crc = *(uint8_t *)(buf + 17 + current_datalen);
+#if alipay_transspecard_log
+ printf("Calculated CRC: 0x%02X, Received CRC: 0x%02X\n", calculated_crc, received_crc);
+#endif
+ if (calculated_crc != received_crc)
+ {
+ printf("CRC check failed for packet %u!\r\n", current_packet_id);
+ isProcessingData = 0;
+ notify_resend(expected_packet_id);
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+
+#if alipay_transspecard_log
+ // 打印接收到的数据
+ printf("Received data for packet %u:\n", current_packet_id);
+ for (int i = 0; i < current_datalen; i++)
+ {
+ printf("%02x ", *(uint8_t *)(buf + 17 + i));
+ }
+ printf("\n");
+#endif
+
+ // 拷贝数据到接收缓冲区
+ memcpy(receive_buffer + (current_packet_id - 1) * (get_alipay_ble_nus_max_data_len() - PACKET_HEAD_AND_TAIL_LEN), buf + 17, current_datalen);
+ packet_received_flags[current_packet_id - 1] = 1;
+
+ // 停止当前定时器(如果存在)
+ if (ble_transspecard_receive_timer != NULL)
+ {
+ osTimerStop(ble_transspecard_receive_timer);
+ osTimerDelete(ble_transspecard_receive_timer);
+ ble_transspecard_receive_timer = NULL;
+ receive_retry_count = 0;
+ }
+
+ // 检查是否是最后一个数据包
+ if (current_packet_id == receive_packet_total)
+ {
+ // 所有数据包都已接收,进行后续处理
+ printf("All packets received, total data length: %u\n", receive_total_datalen);
+#if alipay_transspecard_log
+ // 打印完整数据
+ printf("Complete received data:\n");
+ for (int i = 0; i < receive_total_datalen; i++)
+ {
+ printf("%02x ", receive_buffer[i]);
+ }
+ printf("\n");
+#endif
+ // 这里可以添加对完整数据的处理逻辑,例如调用其他函数进行数据解析等
+ uint8_t ret = alipay_transspecard_sec_type_dispatch(message_type, type_id, receive_buffer, receive_total_datalen);
+ if (ret != ALIPAY_TRANSSPECARD_ERRCODE_SUCC)
+ {
+ printf("alipay_transspecard_sec_type_dispatch failed!\r\n");
+ }
+
+ notify_resend(RECEVIE_PACKET_COMPLETED_ACK); // 通知发送方我已经全部收到数据
+ // 释放资源
+ ble_transspecard_receive_cleanup_resources();
+ }
+ else
+ {
+#if alipay_transspecard_log
+ // 还有未接收的数据包,等待下一个数据包
+ printf("Waiting for packet %u...\n", current_packet_id + 1);
+#endif
+ // 开启定时器等待下一个数据包
+ expected_packet_id = current_packet_id + 1;
+ uint32_t tick = osMs2Tick(PACKET_INTERVAL_TIMEOUT);
+ osStatus_t retTimer;
+ ble_transspecard_receive_timer = osTimerNew((osTimerFunc_t)ble_transspecard_receive_timer_CallBack, osTimerPeriodic, NULL, NULL);
+ retTimer = osTimerStart(ble_transspecard_receive_timer, tick);
+ if (retTimer != osOK && ble_transspecard_receive_timer != NULL) // 启动定时器失败
+ {
+ printf("Start receive timer for packet %u failed, ret = %lx!!", expected_packet_id, retTimer);
+ isProcessingData = 0; // 重置处理标志
+ notify_resend(expected_packet_id); // 通知发送方重新从指定包开始发送
+ osTimerDelete(ble_transspecard_receive_timer);
+ ble_transspecard_receive_timer = NULL;
+ return ALIPAY_TRANSSPECARD_ERRCODE_FAIL;
+ }
+ }
+
+ // 处理完成后,设置标志为0
+ isProcessingData = 0;
+
+ return ALIPAY_TRANSSPECARD_ERRCODE_SUCC;
+}
\ No newline at end of file
--- /dev/null
+#ifndef TRANSSPECARD_H
+#define TRANSSPECARD_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include "stdbool.h"
+#include "bts_def.h"
+#include "errcode.h"
+#include <bleEvent.h>
+
+#define ALIPAY_TRANSSPECARD 0x09
+
+extern uint16_t ble_nus_max_data_len;
+
+typedef uint8_t (*transspecard_pkt_recv_hook)(uint8_t type_id,uint8_t type, void *usr_data, uint16_t usr_len);
+
+typedef struct
+{
+ uint8_t type_id;
+ uint8_t type;
+ transspecard_pkt_recv_hook recv_hook;
+} transspecard_pkt_recv_info_t;
+
+typedef enum transspecard_type_id
+{
+ TRANSSPECARD_TYPE_ID_ALIPAY_NETWORK_STATUS = 0x1, // 网络状态
+ TRANSSPECARD_TYPE_ID_ALIPAY_HOST_INFO, // 主机信息
+ TRANSSPECARD_TYPE_ID_ALIPAY_CONNECT, // 连接
+ TRANSSPECARD_TYPE_ID_ALIPAY_TCPDATA_RECV, // TCP数据接收
+ TRANSSPECARD_TYPE_ID_ALIPAY_CLOSE, // 关闭
+ TRANSSPECARD_TYPE_ID_ALIPAY_TIME_SYNC = 0x7, // 时间同步
+ TRANSSPECARD_TYPE_ID_ALIPAY_ACK = 0xff, // ack回复
+
+} transspecard_type_id_t;
+
+errcode_t msg_center_alipay_receive_ack(uint8_t type_id,uint8_t type, void *usr_data, uint16_t usr_len);
+uint8_t send_transspecard_data(uint8_t type_id, void *data, uint16_t datalen);
+uint8_t parse_transspecard_data(void *buf, uint16_t event_size);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
\ No newline at end of file
set(PRIVATE_HEADER
${ROOT_DIR}/application/wearable/fd230/nativeapp/nativeui/bluetooth/include
${ROOT_DIR}/application/wearable/fd230/nativeapp/nativeui/phoneservice/include/
+ ${ROOT_DIR}/zhihui/services/ble_service/transspecard
)
else()
set(PRIVATE_HEADER
#include "BluetoothWrapper.h"\r
#endif\r
\r
+#include "transspecard.h"\r
+\r
/* HID gatt notification flag, do not need confirm */\r
#define GATT_NOTIFICATION_FLAG 0\r
/* HID gatt indication flag, need confirm */\r
}\r
\r
\r
-errcode_t ble_factorytest_server_send_ota_report(const uint8_t *data, uint8_t len)\r
+errcode_t ble_factorytest_server_send_ota_report(const uint8_t *data, uint16_t len)\r
{\r
// printf("ble_hid_server_send_input_report:%d %d %d",data[0],data[1],len);\r
gatts_ntf_ind_t param = {0};\r
bt_os_free(param.value);\r
return ERRCODE_BT_FAIL;\r
}\r
+\r
+ // printf("发送到app:");\r
+ // for(int i=0;i<len;i++)\r
+ // {\r
+ // printf("%02x ",param.value[i]);\r
+ // }\r
+ // printf("\r\n");\r
+\r
errcode_t ret = 0;\r
ret = gatts_notify_indicate(g_ble_server_id, g_ble_conn_id, ¶m);\r
+ if(ret!=ERRCODE_SUCC)\r
+ {\r
+ printf("发送到app端失败1111\r\n");\r
+ msleep(50);\r
+ ret=gatts_notify_indicate(g_ble_server_id, g_ble_conn_id, ¶m);\r
+ if(ret!=ERRCODE_SUCC)\r
+ {\r
+ printf("发送到app端失败2222\r\n");\r
+ msleep(100);\r
+ ret=gatts_notify_indicate(g_ble_server_id, g_ble_conn_id, ¶m);\r
+\r
+ if(ret!=ERRCODE_SUCC)\r
+ {\r
+ printf("发送到app端失败3333\r\n");\r
+ }\r
+ }\r
+ }\r
printf("ble_factorytest_server_send_ota_report: 0x%x g_ble_conn_id:%d g_factory_ota_report_hdl:%d\r\n",ret,g_ble_conn_id,g_factory_ota_report_hdl);\r
bt_os_free(param.value);\r
return ERRCODE_BT_SUCCESS;\r
}\r
\r
\r
-void factory_recv_ota_data(uint8_t *buf, uint16_t event_size,uint16_t handle)\r
+void factory_recv_ota_data(void *buf, uint16_t event_size,uint16_t handle)\r
{\r
- printf("factory_recv_ota_data len %d , handle 0x%X\r\n",event_size,handle);\r
+ // printf("factory_recv_ota_data len %d , handle 0x%X\r\n",event_size,handle);\r
/****此处为接收指令,处理后反馈结果的参考**/\r
- uint8_t buff[128]={0};\r
- sprintf((char*)buff,"%X",event_size);\r
- ble_factorytest_server_send_ota_report((uint8_t*)buff,strlen((char*)buff));\r
- /*****参考结束****/\r
+ uint8_t ret = parse_transspecard_data(buf, event_size);\r
+ if (ret != 0) {\r
+ WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Failed to parse received data!\r\n");\r
+ }\r
}\r
uint32_t get_factory_ate_write_handl(void);
-void factory_recv_ota_data(uint8_t *buf, uint16_t event_size,uint16_t handle);
+void factory_recv_ota_data(void *buf, uint16_t event_size,uint16_t handle);
void ble_factorytest_store_ota_report_handle(uint16_t srvc_handle);
void ble_factorytest_store_ota_recv_handle(uint16_t srvc_handle);
uint32_t get_factory_ota_write_handl(void);
-errcode_t ble_factorytest_server_send_ota_report(const uint8_t *data, uint8_t len);
+errcode_t ble_factorytest_server_send_ota_report(const uint8_t *data, uint16_t len);
/**
* @}
#include "app_at_process.h"\r
#include "cywee_hal.h"\r
\r
+#ifdef SUPPORT_PPG_SERVICE\r
#include "ppg_service.h"\r
+#endif\r
#include "button_porting.h"\r
#ifdef SUPPORT_CAT1_SERVICE\r
#include "cat1_ctl.h"\r
#include "cat1_server.h"\r
#endif\r
-#ifdef PPG_HX3695\r
+#ifdef SUPPORT_PPG_SERVICE\r
#include "hx3695.h"\r
#include "hx3695_hrs_agc.h"\r
#include "hx3695_spo2_agc.h"\r
#endif\r
\r
#include "battery_service.h"\r
+#ifdef SUPPORT_CYWEE_SERVICE\r
#include "cywee_service.h"\r
+#endif\r
#include "broadcast_feature.h"\r
#ifdef SUPPORT_TCPIP\r
#include "lwip/api_shell.h"\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_SINGLE_CHECK_MODE_TEST);\r
#endif\r
LOS_Msleep(200);\r
- #ifdef PPG_HX3695\r
+ #ifdef SUPPORT_PPG_SERVICE\r
FT_RESULTS_t ft_result = hx3695_factroy_test(SINGLE_CHECK_TEST);\r
#endif\r
#ifdef SUPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
#endif\r
- #ifdef PPG_HX3695\r
+ #ifdef SUPPORT_PPG_SERVICE\r
PRINT("ft_result.gr_data_final : %d , ft_result.red_data_final : %d , ft_result.ir_data_final : %d\r\n",ft_result.gr_data_final,ft_result.red_data_final,ft_result.ir_data_final);\r
if(!(ft_result.gr_data_final && ft_result.red_data_final && ft_result.ir_data_final))\r
{\r
{\r
uint8_t send_data = 0x00;\r
\r
+ #ifdef SUPPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_WEAR_MODE_TEST); \r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_SPO2_TEST); \r
+ #endif\r
\r
uapi_set4GCapability(false);\r
\r
{\r
uint8_t send_data = 0x00;\r
\r
+ #ifdef SUPPORT_CYWEE_SERVICE\r
do_cywee_service_check_msg(CYWEE_SERVICE_CMD_STOP_ACC,NULL);\r
+ #endif\r
stop_custom_ble_service();\r
LOS_Msleep(50);\r
uapi_set4GCapability(false);\r
{\r
//关闭所有LED\r
uint8_t send_data = 0x00;\r
+ #ifdef SUPPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_LED_OFF_MODE_TEST);\r
+ #endif\r
factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
BLE_TEST_CMD_SOFT_TEST_SUB_MODE_HRS,\r
0x02,\r
} else if(testitem == 0x03)\r
{\r
//打开心率检测\r
-#ifdef PPG_HX3695\r
+#ifdef SUPPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_SINGLE_CHECK_MODE_TEST);\r
#elif defined PPG_VC9202\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_PPG_TEST);\r
#endif\r
LOS_Msleep(500);\r
uint8_t databuf[4] = {0};\r
-#ifdef PPG_HX3695\r
+#ifdef SUPPORT_PPG_SERVICE\r
FT_RESULTS_t ft_result = hx3695_factroy_test(SINGLE_CHECK_TEST);\r
databuf[0] = (uint8_t)((ft_result.gr_data_final & 0xFF000000) >> 24);\r
databuf[1] = (uint8_t)((ft_result.gr_data_final & 0x00FF0000) >> 16);\r
databuf[3] = (uint8_t)((ppg_data & 0x000000FF) >> 0);\r
#endif\r
\r
+ #ifdef SUPPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
+ #endif\r
\r
PRINT("%2X %2X %2X %2X \r\n",databuf[0],databuf[1],databuf[2],databuf[3]);\r
\r
} else if(testitem == 0x04)\r
{\r
//打开血氧检测\r
-#ifdef PPG_HX3695\r
+#ifdef SUPPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_SINGLE_CHECK_MODE_TEST);\r
#elif defined PPG_VC9202\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_SPO2_TEST);\r
#endif\r
LOS_Msleep(500);\r
uint8_t databuf[8] = {0};\r
-#ifdef PPG_HX3695\r
+#ifdef SUPPORT_PPG_SERVICE\r
FT_RESULTS_t ft_result = hx3695_factroy_test(SINGLE_CHECK_TEST);\r
databuf[0] = (uint8_t)((ft_result.red_data_final & 0xFF000000) >> 24);\r
databuf[1] = (uint8_t)((ft_result.red_data_final & 0x00FF0000) >> 16);\r
databuf[6] = (uint8_t)((red_data & 0x0000FF00) >> 8);\r
databuf[7] = (uint8_t)((red_data & 0x000000FF) >> 0);\r
#endif\r
+ #ifdef SUPPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
+ #endif\r
PRINT("%2X %2X %2X %2X \r\n",databuf[0],databuf[1],databuf[2],databuf[3]);\r
PRINT("%2X %2X %2X %2X \r\n",databuf[4],databuf[5],databuf[6],databuf[7]);\r
\r
} else if(testitem == 0x05)\r
{\r
//灰卡测试\r
+ #ifdef SUPPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_GRAYCARD_TEST);\r
+ #endif\r
LOS_Msleep(500);\r
-#ifdef PPG_HX3695\r
+#ifdef SUPPORT_PPG_SERVICE\r
uint8_t databuf[12] = {0};\r
FT_RESULTS_t ft_result = hx3695_factroy_test(GRAY_CARD_TEST);\r
databuf[0] = (uint8_t)((ft_result.gr_data_final & 0xFF000000) >> 24);\r
databuf,\r
8);\r
#endif\r
+ #ifdef SUPPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
+ #endif\r
// PRINT("%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\r\n",\r
// databuf[0],databuf[1],databuf[2],databuf[3],\r
// databuf[4],databuf[5],databuf[6],databuf[7],\r
} else if(testitem == 0x06)\r
{\r
//漏光测试\r
+ #ifdef SUPPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST);\r
+ #endif\r
LOS_Msleep(500);\r
uint8_t databuf[12] = {0};\r
-#ifdef PPG_HX3695\r
+#ifdef SUPPORT_PPG_SERVICE\r
FT_RESULTS_t ft_result = hx3695_factroy_test(LEAK_LIGHT_TEST);\r
\r
databuf[0] = (uint8_t)((ft_result.gr_data_final & 0xFF000000) >> 24);\r
databuf[10] = (uint8_t)((aps_val & 0x0000FF00) >> 8);\r
databuf[11] = (uint8_t)((aps_val & 0x000000FF) >> 0);\r
#endif\r
+ #ifdef SUPPORT_PPG_SERVICE\r
send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);\r
+ #endif\r
\r
// PRINT("%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\r\n",\r
// databuf[0],databuf[1],databuf[2],databuf[3],\r