yy1717
2021-01-12 683b1595260e638d1d3c6cc0d6543a72f6d6f925
扣分码标准化
35个文件已修改
2个文件已添加
1796 ■■■■■ 已修改文件
lib/src/main/cpp/CMakeLists.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/defs.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/driver_test.cpp 96 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/driver_test.h 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/master/comm_if.cpp 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/master/comm_if.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/mcu/mcu_if.cpp 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/mcu/mcu_if.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/native-lib.cpp 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/native-lib.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/rtk_module/rtk.cpp 193 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/rtk_module/rtk.h 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/rtk_module/virtual_rtk.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/rtk_platform/parse_net.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/rtk_platform/platform.cpp 606 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/rtk_platform/platform.h 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_common/car_sensor.cpp 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items/driving_curve.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items/park_bottom.cpp 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items/park_edge.cpp 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items/stop_and_start.cpp 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items/turn_a90.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/car_start.cpp 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/change_lane.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/drive_straight.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/dummy_light.cpp 199 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/dummy_light.h 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/operate_gear.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/overtake.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/prepare.cpp 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/prepare.h 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/road_exam.cpp 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/stop_car.cpp 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/through_something.cpp 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/java/com/anyun/exam/lib/InstallUtil.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/java/com/anyun/exam/lib/RemoteService.java 47 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/java/com/anyun/exam/lib/Upgrade.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/CMakeLists.txt
@@ -38,6 +38,7 @@
        test_items/turn_a90.cpp
        test_items/area_exam.cpp
        test_items2/prepare.cpp
        test_items2/common_check.cpp
        test_items2/dummy_light.cpp
        test_items2/road_exam.cpp
lib/src/main/cpp/defs.h
@@ -1,8 +1,8 @@
#ifndef _DEFS_H_
#define _DEFS_H_
#include <stdint.h>
#include <stdbool.h>
#include <cstdint>
#include <cstdbool>
#define ENABLE_DEBUG
lib/src/main/cpp/driver_test.cpp
@@ -37,6 +37,7 @@
#include "test_common/car_sensor.h"
#include "test_items2/road_exam.h"
#include "test_items/area_exam.h"
#include "test_items2/prepare.h"
#define DEBUG(fmt, args...)     LOGD("<driver_test> <%s>: " fmt, __func__, ##args)
@@ -86,6 +87,12 @@
static const int DEFAULT_START_CAR_MAX_RMP = 2500;
static const int DEFAULT_START_CAR_DISTANCE = 10;
static const double DEFAULT_START_CAR_OPEN_DOOR_DISTANCE = 1.0;
static const char DEFAULT_PREPARE_TTS[] = "请开始上车准备";
static const char DEFAULT_TOUCH_LEFT_FRONT[] = "学员通过左前方";
static const char DEFAULT_TOUCH_LEFT_REAR[] = "学员通过左后方";
static const char DEFAULT_TOUCH_RIGHT_FRONT[] = "学员通过右前方";
static const char DEFAULT_TOUCH_RIGHT_REAR[] = "学员通过右后方";
static const char DEFAULT_START_ENGINE[] = "请启动发动机";
static const char DEFAULT_START_CAR_BEGIN_TTS[] = "请起步,继续完成考试";
static const char DEFAULT_START_CAR_END_TTS[] = "起步完成";
static const int CHANGE_LANE_MAX_DISTANCE = 100;
@@ -235,6 +242,14 @@
    examParam.start_car_max_rpm = DEFAULT_START_CAR_MAX_RMP;
    examParam.start_car_limit_distance = DEFAULT_START_CAR_DISTANCE;
    examParam.open_door_drive_allow_distance = DEFAULT_START_CAR_OPEN_DOOR_DISTANCE;
    examParam.prepare_tts = DEFAULT_PREPARE_TTS;
    examParam.touch_leftfront_tts = DEFAULT_TOUCH_LEFT_FRONT;
    examParam.touch_leftrear_tts = DEFAULT_TOUCH_LEFT_REAR;
    examParam.touch_rightfront_tts = DEFAULT_TOUCH_RIGHT_FRONT;
    examParam.touch_rightrear_tts = DEFAULT_TOUCH_RIGHT_REAR;
    examParam.start_engine_tts = DEFAULT_START_ENGINE;
    examParam.start_car_begin_tts = DEFAULT_START_CAR_BEGIN_TTS;
    examParam.start_car_end_tts = DEFAULT_START_CAR_END_TTS;
    examParam.change_lane_limit_distance = CHANGE_LANE_MAX_DISTANCE;
@@ -371,7 +386,7 @@
    RoadMap.examScheme.assign(scheme.begin(), scheme.end());
    DEBUG("得到新的路考地图 项目数量 %d", RoadMap.examScheme.size());
    DEBUG("得到路考项目方案 项目数量 %d", RoadMap.examScheme.size());
}
void SetCarMeasurePoint(double *basePoint, int *axial, int *left_front_tire,
@@ -505,18 +520,38 @@
{
    DEBUG("获取模拟路考灯光测试项目 N = %d %d", n, ExamStart);
    static const int cov[] = {0,
                              (DIPPED_BEAM_LAMP<<8)+DIPPED_BEAM_LIGHT,
                              (MAIN_BEAM_LAMP<<8)+MAIN_BEAM_LIGHT,
                              (CLEARANCE_LAMP<<8)+CLEARANCE_LIGHT,
                              (FOG_LAMP<<8)+FOG_LIGHT,
                              (TURN_SIGNAL_LAMP<<8)+LEFT_TURN_LIGHT,
                              (TURN_SIGNAL_LAMP<<8)+RIGHT_TURN_LIGHT,
                              (TURN_SIGNAL_LAMP<<8)+HAZARD_LIGHTS,
                              (FLASH_BEAM_LAMP<<8)+FLASH_BEAM_LIGHT};
    if (ExamStart) return;
    if (DummyLightContent != NULL) {
        free(DummyLightContent);
        delete []DummyLightContent;
        DummyLightContent = NULL;
        DummyLightContentSize = 0;
    }
    DummyLightContent = (struct dummy_light_exam *)malloc(n * sizeof(struct dummy_light_exam));
    DummyLightContent = new struct dummy_light_exam[n];
    DummyLightContentSize = n;
    for (int i = 0; i < n; i++) {
        DummyLightContent[i] = cfg[i];
        DummyLightContent[i].item = cfg[i].item;
        DummyLightContent[i].tts = cfg[i].tts;
        DummyLightContent[i].wrongCode = cfg[i].wrongCode;
        // Sensor Name<<8 + Sensor Status
        for (int j = 0; j < cfg[i].process.size(); ++j) {
            DummyLightContent[i].process[j] = cov[cfg[i].process[j]];
        }
        for (int j = 0; j < cfg[i].solution.size(); ++j) {
            DummyLightContent[i].solution[j] = cov[cfg[i].solution[j]];
        }
    }
}
@@ -688,8 +723,6 @@
    }
}
static void PrintObdInfo(struct RtkTime *rtkTime, double speed) {
    static struct RtkTime cTime = *rtkTime;
@@ -791,9 +824,9 @@
            engineRuning = false;
            if (ExamType == TEST_TYPE_AREA) {
                // 熄火1次,扣10分
                AddExamFault(5, rtkTime);
                AddExamFault(10210, rtkTime);
            } else {
                AddExamFault(20, rtkTime);
                AddExamFault(30208, rtkTime);
            }
        }
    } else {
@@ -806,9 +839,9 @@
            if (ReadCarStatus(GEAR) != GEAR_N) {
                // 不是空挡点火,不合格
                if (ExamType == TEST_TYPE_AREA)
                    AddExamFault(3, rtkTime);
                    AddExamFault(10105, rtkTime);
                else
                    AddExamFault(4, rtkTime);
                    AddExamFault(30105, rtkTime);
            }
            AppTimer_delete(EngineStartHold);
            AppTimer_add(EngineStartHold, examParam.hold_start_key_limit_time);
@@ -823,19 +856,23 @@
        // 不及时松开启动开关,扣10分
        if (ExamType == TEST_TYPE_AREA)
            AddExamFault(4, rtkTime);
            AddExamFault(10201, rtkTime);
    }
    if (ExamType == TEST_TYPE_ROAD_DUMMY_LIGHT) {
        if (exam_dummy_light == 0) {
            StartDummyLightExam(DummyLightContent, DummyLightContentSize, rtkTime);
            StartPrepare();
//            StartDummyLightExam(DummyLightContent, DummyLightContentSize, rtkTime);
            exam_dummy_light = 1;
            // 汇报灯光考试开始
            DEBUG("灯光考试开始");
        } else if (exam_dummy_light == 1) {
            exam_dummy_light = ExecuteDummyLightExam(rtkTime);
            // 汇报灯光考试结束
            if (exam_dummy_light == 2) {
            DEBUG("开始上车准备");
        } else if (exam_dummy_light == 2) {
            DEBUG("开始灯光考试");
            StartDummyLightExam(DummyLightContent, DummyLightContentSize, rtkTime);
            exam_dummy_light = 3;
        } else if (exam_dummy_light == 3) {
            if (!ExecuteDummyLightExam(rtkTime)) {
                exam_dummy_light = 4;
                // 汇报灯光考试结束
                DEBUG("灯光考试结束");
                InitRoadExam(RoadMap);
            }
@@ -849,12 +886,12 @@
        if (ReadCarStatus(SEATBELT) == EJECT_SEATBELT && !reportSeatbeltEject) {
            DEBUG("不系安全带");
            reportSeatbeltEject = true;
            AddExamFault(1, rtkTime);
            AddExamFault(ExamType == TEST_TYPE_AREA? 10101: 30101, rtkTime);
        }
    }
    if (ExamType != TEST_TYPE_AREA) {
        if (exam_dummy_light == 2 || ExamType == TEST_TYPE_ROAD_TRUE_LIGHT || ExamType == TEST_TYPE_ROAD_CALIBRATE) {
        if (exam_dummy_light == 4 || ExamType == TEST_TYPE_ROAD_TRUE_LIGHT || ExamType == TEST_TYPE_ROAD_CALIBRATE) {
            TestRoadGeneral(RoadMap, CarModel, CarModelList, speed, move, rtkTime);
        }
    } else {
@@ -1089,13 +1126,13 @@
    sprintf(fault.utc, "%04d%02d%02d%02d%02d%02d.%02d", 2000 + rtkTime->YY,
            rtkTime->MM, rtkTime->DD, rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss);
    if (ExamType != TEST_TYPE_AREA) {
        wrong += 1000;
    }
//    if (ExamType != TEST_TYPE_AREA) {
//        wrong += 1000;
//    }
    fault.wrong_id = wrong;
    DEBUG("考试发生错误 %d %s", wrong, fault.utc);
    DEBUG("考试发生错误 code = %d %s", wrong, fault.utc);
    ExamFaultList.push_back(fault);
@@ -1204,3 +1241,14 @@
    }
}
void SensorXChanged(uint16_t id, int value)
{
    handlePrepare(id, value);
    handleLigthExam(id, value);
}
void PrepareOver(int res)
{
    exam_dummy_light = 2;
}
lib/src/main/cpp/driver_test.h
@@ -247,6 +247,14 @@
    int start_car_max_rpm;
    int start_car_limit_distance;
    double open_door_drive_allow_distance;
    string prepare_tts;
    string touch_leftfront_tts;
    string touch_leftrear_tts;
    string touch_rightfront_tts;
    string touch_rightrear_tts;
    string start_engine_tts;
    string start_car_begin_tts;
    string start_car_end_tts;
@@ -325,4 +333,6 @@
int CorrectPauseCriteria(int src);
void SensorXChanged(uint16_t id, int value);
#endif //RTKDRIVERTEST_DRIVER_TEST_H
lib/src/main/cpp/master/comm_if.cpp
@@ -22,6 +22,7 @@
#include <vector>
#include <list>
#include <semaphore.h>
#include <unistd.h>
#define DEBUG(fmt, args...)     LOGD("<comm_if> <%s>: " fmt, __func__, ##args)
@@ -74,6 +75,8 @@
#define ID_SM_CAN_BRIEF         0x0021
#define ID_SM_BLUETOOTH_BRIEF   0x0022
#define ID_SM_RTK_STATUS_BRIEF  0x0023
#define MA_OUT_GPS_BRIEF        0x0001
#define MA_OUT_RTK_BRIEF        0x0002
#define MA_OUT_CAR_BRIEF        0x0004
@@ -121,16 +124,26 @@
        if (MessageBuffer.size() > 0) {
            struct msg_2_main_t msg;
            int success;
            pthread_mutex_lock(&msg_mutex);
            msg = MessageBuffer.back();
            MessageBuffer.pop_back();
            pthread_mutex_unlock(&msg_mutex);
            if (msg.value.length() > 0)
                SendMsgToMainProc(msg.cmd, msg.value.c_str());
                success = SendMsgToMainProc(msg.cmd, msg.value.c_str());
            else
                SendMsgToMainProc(msg.cmd, NULL);
                success = SendMsgToMainProc(msg.cmd, NULL);
            if (success == 0) {
                pthread_mutex_lock(&msg_mutex);
                MessageBuffer.pop_back();
                pthread_mutex_unlock(&msg_mutex);
            } else {
                // 延迟重发
                usleep(500000);
                sem_post(&sem_msg_income);
            }
        }
    }
}
@@ -646,6 +659,7 @@
{
    switch (cmd) {
        case ID_MS_RTK_PLAT_CFG: {
            DEBUG("平台信息 %s", value);
            if (OnOff == 0) OnOff = MA_OUT_GPS_BRIEF + MA_OUT_RTK_BRIEF + MA_OUT_CAR_BRIEF;
            rtk_platform_cfg_t cfg;
@@ -1971,9 +1985,28 @@
                                const Value &s2 = (*itr)["tts"];
                                content[n].item = s1.GetInt();
                                strcpy(content[n].tts, s2.GetString());
                                n++;
                                content[n].tts = s2.GetString();
                            }
                            if (itr->HasMember("wrong_code")) {
                                const Value &s = (*itr)["wrong_code"];
                                content[n].wrongCode = s.GetInt();
                            }
                            if (itr->HasMember("process")) {
                                const Value& s = doc["process"];
                                for(Value::ConstValueIterator itr2 = s.Begin(); itr2 != s.End(); ++itr2) {
                                    content[n].process.push_back(itr2->GetInt());
                                }
                            }
                            if (itr->HasMember("solution")) {
                                const Value& s = doc["solution"];
                                for(Value::ConstValueIterator itr2 = s.Begin(); itr2 != s.End(); ++itr2) {
                                    content[n].solution.push_back(itr2->GetInt());
                                }
                            }
                            n++;
                        }
                        SetDummyLightExam(n, content);
@@ -2063,3 +2096,25 @@
    SendMsgToMainProcIndep(ID_SM_BLUETOOTH_BRIEF, sb.GetString());
}
void MA_SendRtkStatus(const char *model, int status)
{
    StringBuffer sb;
    Writer<StringBuffer> writer(sb);
    writer.StartObject();
    writer.Key("model");
    if (model == NULL || model[0] == 0) {
        writer.String("Unknown");
    } else {
        writer.String(model);
    }
    writer.Key("status");
    writer.Int(status);
    writer.EndObject();
    SendMsgToMainProcIndep(ID_SM_RTK_STATUS_BRIEF, sb.GetString());
}
lib/src/main/cpp/master/comm_if.h
@@ -154,5 +154,6 @@
void MA_SendCanStatus(const struct canBrief *brief);
void MA_SendBlueStatus(const char *name, const char *addr, int status);
void MA_SendRtkStatus(const char *type, int status);
#endif //MYAPPLICATION2_COMM_IF_H
lib/src/main/cpp/mcu/mcu_if.cpp
@@ -14,6 +14,7 @@
#include "../rtk_platform/platform.h"
#include "../rtk_module/parse_gps.h"
#include "../native-lib.h"
#include "../rtk_module/virtual_rtk.h"
#define DEBUG(fmt, args...)     LOGD("<mcu_if> <%s>: " fmt, __func__, ##args)
@@ -277,25 +278,29 @@
    WriteMcu(MCU_UART, buffer, x);
}
void ConfigMCU(void)
void ConfigMCU(bool ayDevice)
{
    McuCommModeSel(1);
    if (ayDevice) {
        McuCommModeSel(0);
    // TODO
  /*  static struct serial_config serialConfig;
        // TODO
        static struct serial_config serialConfig;
    strcpy(serialConfig.name, "/dev/ttyHSL1");
    serialConfig.baud = 115200;
    serialConfig.data_bit = 8;
    serialConfig.verify_bit = 'N';
    serialConfig.stop_bit = 1;
    serialConfig.flow_ctrl = 0;
        strcpy(serialConfig.name, "/dev/ttyHSL1");
        serialConfig.baud = 115200;
        serialConfig.data_bit = 8;
        serialConfig.verify_bit = 'N';
        serialConfig.stop_bit = 1;
        serialConfig.flow_ctrl = 0;
    pthread_t pid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached
    pthread_create(&pid, &attr, UartThread1, &serialConfig);*/
        pthread_t pid;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached
        pthread_create(&pid, &attr, UartThread1, &serialConfig);
    } else {
        McuCommModeSel(1);
    }
}
void SendRtkToMcu(const uint8_t *data, int length)
@@ -417,14 +422,29 @@
            memcpy(GnssBuf + GnssBufLen, data, length);
            GnssBufLen += length;
            if (GnssBufLen > 0) {
                const uint8_t *ptr = parseGPS(GnssBuf, GnssBuf + GnssBufLen);
                if (ptr != GnssBuf) {
                    memcpy(GnssBuf, ptr, GnssBufLen - (ptr - GnssBuf));
                    GnssBufLen -= ptr - GnssBuf;
                } else if (GnssBufLen == PARSE_BUFF_SIZE) {        //填满了,且没有一个\r,都抛弃
                    DEBUG("Parse GPS error");
                if (VirtualIsConnected()) {     //PC模拟用时
                    static bool first = false;
                    if (!first) {
                        first = true;
                        uint8_t buff[33] = "emulator";
                        buff[32] = 1;
                        PlatformStatusChanged(RTK_STATUS_EVT, buff, 33);
                    }
                    GnssBufLen = 0;
                } else {
                    const uint8_t *ptr = parseGPS(GnssBuf, GnssBuf + GnssBufLen);
                    if (ptr != GnssBuf) {
                        memcpy(GnssBuf, ptr, GnssBufLen - (ptr - GnssBuf));
                        GnssBufLen -= ptr - GnssBuf;
                    } else if (GnssBufLen == PARSE_BUFF_SIZE) {        //填满了,且没有一个\r,都抛弃
                        DEBUG("Parse GPS error");
                        GnssBufLen = 0;
                    }
                }
            }
            break;
lib/src/main/cpp/mcu/mcu_if.h
@@ -8,7 +8,7 @@
#include <cstdint>
void McuCommModeSel(int mode);
void ConfigMCU(void);
void ConfigMCU(bool ayDevice);
void SendRtkToMcu(const uint8_t *data, int length);
void ParseMcuInit(void);
void ParseMcu(const uint8_t *data, int length);
lib/src/main/cpp/native-lib.cpp
@@ -35,8 +35,6 @@
static int ttsSeq = 1;
static void SendBootIndicate(union sigval sig);
static std::map<int, void (*)(int)> TTSCallBack;
int DESEncrypt(const uint8_t *key, int key_length,
@@ -173,25 +171,26 @@
    }
}
void SendMsgToMainProc(int cmd, const char *value)
int SendMsgToMainProc(int cmd, const char *value)
{
    JNIEnv *env;
    bool ready_in_java_env = false;
    int ret;
    if (sg_jvm->GetEnv((void **)&env, JNI_VERSION_1_6) != JNI_OK) {
        // Attach主线程
        if (sg_jvm->AttachCurrentThread(&env, NULL) != JNI_OK) {
            LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
            return;
            return -3;
        }
    } else {
        ready_in_java_env = true;
    }
    jclass cls = env->GetObjectClass(sg_obj);
    jmethodID fun = env->GetMethodID(cls, "SendMsgToMainProc", "(ILjava/lang/String;)V");
    jmethodID fun = env->GetMethodID(cls, "SendMsgToMainProc", "(ILjava/lang/String;)I");
    env->CallVoidMethod(sg_obj, fun, cmd, value != NULL ? env->NewStringUTF(value) : NULL);
    ret = env->CallIntMethod(sg_obj, fun, cmd, value != NULL ? env->NewStringUTF(value) : NULL);
    env->DeleteLocalRef(cls);
@@ -201,6 +200,8 @@
            LOGE("%s: DetachCurrentThread() failed", __FUNCTION__);
        }
    }
    return ret;
}
static int GetTtsSeq(void)
@@ -384,7 +385,7 @@
extern "C"
JNIEXPORT void JNICALL
Java_com_anyun_exam_lib_RemoteService_startNative(JNIEnv *env, jobject thiz) {
Java_com_anyun_exam_lib_RemoteService_startNative(JNIEnv *env, jobject thiz, jboolean ayDevice) {
    // TODO: implement startNative()
    // 保存全局JVM以便在子线程中使用
    DEBUG("启动Native");
@@ -395,28 +396,17 @@
    srand(time(NULL));
    AppTimer_Init();
    ConfigMCU();
    ConfigMCU(ayDevice);
    DriverTestInit();
    ConfigRTKModule();
    ConfigRTKModule(ayDevice);
    MA_Init();
    InitPlatform(phone, RTK_PLATFORM_IP, RTK_PLATFORM_PORT);
    AppTimer_add(SendBootIndicate, D_SEC(1));
    InitPlatform(ayDevice, phone, RTK_PLATFORM_IP, RTK_PLATFORM_PORT);
    InitVirtualDevice(VIRTUAL_RTK_IP, VIRTUAL_RTK_PORT);
    pthread_mutex_init(&tts_mutex, NULL);
}
static void SendBootIndicate(union sigval sig) {
    static int n = 0;
    AppTimer_delete(SendBootIndicate);
    MA_NdkStart();
    n++;
    if (n < 3) {
        AppTimer_add(SendBootIndicate, D_SEC(1));
    }
}
extern "C"
lib/src/main/cpp/native-lib.h
@@ -24,7 +24,7 @@
void TextOsd(int type, const char *text);
void DrawScreen(const Polygon *map, const Polygon *car);
void SendMsgToMainProc(int cmd, const char *value);
int SendMsgToMainProc(int cmd, const char *value);
int PlayTTS(const char *string, void (*callback)(int));
int PlayTTS(std::string &tts, void (*callback)(int));
void PlayRing(void);
lib/src/main/cpp/rtk_module/rtk.cpp
@@ -36,17 +36,24 @@
const static char SAVECONFIG[] = "saveconfig\r\n";
const static char *PJKITEMS[] = {"gptra", "ptnlpjk"};
const static char *GPSITEMS[] = {"gpgga", "gprmc", "gpvtg"};
const char CMD_VERSION[] = "log version\r\n";
static gpsStatus_t gpsStatus;
static char rtkModel[32] = {0};
static int (*WriteRtk)(int id, const void *buf, int len);
static rtk_info CurrRTKInfo;
static bool needSetPjk = false;
static int lostCnt;
static void CheckPjkParam(void);
static void CheckPjkParamTimeout(union sigval sig);
static int WriteBluetooth(int id, const void *buf, int len);
static void GetModuleVersion(void);
static void VersionTimeout(union sigval sig);
static void GpsDataTimeout(union sigval sig);
static void *UartThread(void *p);
@@ -59,7 +66,7 @@
    }
}
void ConfigRTKModule(void)
void ConfigRTKModule(bool ayDevice)
{
    // TODO
    DEBUG("ConfigRTKModule");
@@ -70,26 +77,34 @@
    memset(&gpsStatus, 0, sizeof(gpsStatus));
    gpsStatus.hh = -1;
    RtkCommModeSel(1);
    if (ayDevice) {
        RtkCommModeSel(0);
    /*static struct serial_config serialConfig;
        static struct serial_config serialConfig;
    strcpy(serialConfig.name, "/dev/ttyHSL0");
    serialConfig.baud = 115200;
    serialConfig.data_bit = 8;
    serialConfig.verify_bit = 'N';
    serialConfig.stop_bit = 1;
    serialConfig.flow_ctrl = 0;
        strcpy(serialConfig.name, "/dev/ttyHSL0");
        serialConfig.baud = 115200;
        serialConfig.data_bit = 8;
        serialConfig.verify_bit = 'N';
        serialConfig.stop_bit = 1;
        serialConfig.flow_ctrl = 0;
    pthread_t pid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached
    pthread_create(&pid, &attr, UartThread, &serialConfig);*/
        pthread_t pid;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached
        pthread_create(&pid, &attr, UartThread, &serialConfig);
    } else {
        RtkCommModeSel(1);
        // 等待蓝牙连接
    }
}
// 蓝牙连接后
void ConfigRTKModuleLater(void)
{
    AppTimer_delete(GpsDataTimeout);
    AppTimer_delete(VersionTimeout);
    AppTimer_delete(CheckPjkParamTimeout);
    AppTimer_add(CheckPjkParamTimeout, D_SEC(1));
}
@@ -107,59 +122,27 @@
void handleRTKRebootComp(const struct nmea *s)
{
    DEBUG("RTK Reboot complete!!");
    CheckPjkParam();
//    CheckPjkParam();
    GetModuleVersion();
}
void handlePJKParam(const struct nmea *s) {
    DEBUG("handlePJKParam");
//PJK Parameter: A:6378137.000, 1/F:298.257223563, B0:0.000000deg, L0:120.000000, N0:0.000, E0:500000.000.
//PJK Parameter: A:6378137.000, 1/F:298.257223563, B0:29.512453deg, L0:106.455336, N0:0.000, E0:0.000.
//    bool setparam = true;
//
//    const char DP1[] = "A:6378137.000";
//    const char DP2[] = "1/F:298.257223563";
//    const char DP3[] = "B0:29.512453deg";
//    const char DP4[] = "L0:106.455336";
//    const char DP5[] = "N0:0.000";
//    const char DP6[] = "E0:0.000";
    AppTimer_delete(CheckPjkParamTimeout);
//    for (int i = 0; i < s->nmea_num; ++i) {
//        char out[64] = {0};
//
//        memcpy(out, s->nmea_value[i].data, s->nmea_value[i].length);
//
//        DEBUG("handlePJKParam = %s", out);
//    }
//
//    if (s->nmea_num != 6) return;
//
//    if (memcmp(s->nmea_value[0].data, DP1, strlen(DP1))) {
//        setparam = true;
//    }
//    if (memcmp(s->nmea_value[1].data, DP2, strlen(DP2))) {
//        setparam = true;
//    }
//    if (memcmp(s->nmea_value[2].data, DP3, strlen(DP3))) {
//        setparam = true;
//    }
//    if (memcmp(s->nmea_value[3].data, DP4, strlen(DP4))) {
//        setparam = true;
//    }
//    if (memcmp(s->nmea_value[4].data, DP5, strlen(DP5))) {
//        setparam = true;
//    }
//    if (memcmp(s->nmea_value[5].data, DP6, strlen(DP6))) {
//        setparam = true;
//    }
//
//    if (setparam) {
//        SetAYFactoryParam(5);
//    }
    SetAYFactoryParam(5);
    needSetPjk = true;
    lostCnt = 0;
    AppTimer_delete(GpsDataTimeout);
    AppTimer_add(GpsDataTimeout, D_SEC(5));
    uint8_t buff[33];
    memcpy(buff, rtkModel, 32);
    buff[32] = 1;
    PlatformStatusChanged(RTK_STATUS_EVT, buff, 33);
}
void SetAYFactoryParam(int freq)
@@ -211,7 +194,8 @@
    int RxBufLen = 0;
    if (res == 0) {
        CheckPjkParam();
//        CheckPjkParam();
        GetModuleVersion();
    }
    while (res == 0) {
@@ -240,6 +224,15 @@
        if (RxBufLen > 0) {
#if 1
            if (VirtualIsConnected()) {     //PC模拟用时
                static bool first = false;
                if (!first) {
                    first = true;
                    uint8_t buff[33] = "emulator";
                    buff[32] = 1;
                    PlatformStatusChanged(RTK_STATUS_EVT, buff, 33);
                }
                RxBufLen = 0;
            } else {
                const uint8_t *ptr = parseGPS(RxBuf, RxBuf + RxBufLen);
@@ -263,17 +256,41 @@
}
void handleUnrecognisedNMEA(const uint8_t *data, uint16_t length) {
//    char buff[4096] = {0};
//    memcpy(buff, data, MIN(length, 3000));
    char buff[4096] = {0};
    memcpy(buff, data, MIN(length, 4000));
//    DEBUG("handleUnrecognisedNMEA: %s", buff);
    if (length >= 100) {
        string cs(buff);
        if (cs.find("K708") != string::npos) {
            // 最初的标准基站模块
            DEBUG("K708 模块");
            strcpy(rtkModel, "K708");
            AppTimer_delete(VersionTimeout);
            CheckPjkParam();
        } else if (cs.find("K726") != string::npos) {
            // 移动站模块,也可以用做基站功能
            DEBUG("K726 模块");
            strcpy(rtkModel, "K726");
            AppTimer_delete(VersionTimeout);
            CheckPjkParam();
        }
    }
}
void handleGPGGA(const struct nmea *s)
{
    static uint32_t qfCnt = 0;
    DEBUG("handleGPGGA num = %d", s->nmea_num);
//    DEBUG("handleGPGGA num = %d", s->nmea_num);
    if (s->nmea_num >= 10) {
        lostCnt = 0;
        AppTimer_delete(GpsDataTimeout);
        AppTimer_add(GpsDataTimeout, D_SEC(5));
        gpsStatus.gps_status = str2int(s->nmea_value[5].data, s->nmea_value[5].length);
        int hh = str2int(s->nmea_value[0].data, 2);
@@ -331,7 +348,7 @@
void handleGPRMC(const struct nmea *s)
{
    DEBUG("handleGPRMC num = %d", s->nmea_num);
//    DEBUG("handleGPRMC num = %d", s->nmea_num);
    if (s->nmea_num >= 9) {
        int hh = str2int(s->nmea_value[0].data, 2);
@@ -397,7 +414,7 @@
}
void handlePJK(const struct nmea *s) {
    DEBUG("handlePJK num = %d", s->nmea_num);
//    DEBUG("handlePJK num = %d", s->nmea_num);
    int hh = str2int(s->nmea_value[0].data, 2);
    int mm = str2int(s->nmea_value[0].data + 2, 2);
@@ -457,7 +474,7 @@
}
void handleGPTRA(const struct nmea *s) {
    DEBUG("handleGPTRA num = %d", s->nmea_num);
//    DEBUG("handleGPTRA num = %d", s->nmea_num);
    int hh = str2int(s->nmea_value[0].data, 2);
    int mm = str2int(s->nmea_value[0].data + 2, 2);
@@ -491,8 +508,8 @@
static void CheckPjkParam(void)
{
    int n = WriteRtk(RTK_MODULE_UART, INQ_PJK_PARAM, strlen(INQ_PJK_PARAM));
    DEBUG("CN = %d", n);
    WriteRtk(RTK_MODULE_UART, INQ_PJK_PARAM, strlen(INQ_PJK_PARAM));
    DEBUG("获取PJK参数...");
    AppTimer_delete(CheckPjkParamTimeout);
    AppTimer_add(CheckPjkParamTimeout, D_SEC(3));
}
@@ -500,11 +517,14 @@
static void CheckPjkParamTimeout(union sigval sig) {
    AppTimer_delete(CheckPjkParamTimeout);
    DEBUG("RTK Module failure!!");
    DEBUG("获取PJK参数超时");
//    PlayTTS("RTK模块无法通讯", NULL);
    uint8_t buff[33];
    memcpy(buff, rtkModel, 32);
    buff[32] = 0;
    PlatformStatusChanged(RTK_STATUS_EVT, buff, 33);
    CheckPjkParam();
    GetModuleVersion();
}
static int WriteBluetooth(int id, const void *buf, int len)
@@ -513,3 +533,36 @@
    SendMcuCommand(0x000B, (uint8_t *)buf, len);
    return len;
}
static void GetModuleVersion(void)
{
    AppTimer_delete(VersionTimeout);
    AppTimer_add(VersionTimeout, D_SEC(3));
    WriteRtk(RTK_MODULE_UART, CMD_VERSION, strlen(CMD_VERSION));
    DEBUG("获取版本...");
}
static void VersionTimeout(union sigval sig)
{
    AppTimer_delete(VersionTimeout);
    DEBUG("版本获取超时");
    GetModuleVersion();
    uint8_t buff[33];
    memcpy(buff, rtkModel, 32);
    buff[32] = 0;
    PlatformStatusChanged(RTK_STATUS_EVT, buff, 33);
}
static void GpsDataTimeout(union sigval sig)
{
    AppTimer_delete(GpsDataTimeout);
    if (++lostCnt >= 3) {
        DEBUG("RTK模块收不到GPS数据");
        GetModuleVersion();
    } else {
        AppTimer_add(GpsDataTimeout, D_SEC(5));
    }
}
lib/src/main/cpp/rtk_module/rtk.h
@@ -40,7 +40,7 @@
}rtk_info;
void RtkCommModeSel(int mode);
void ConfigRTKModule(void);
void ConfigRTKModule(bool ayDevice);
void ConfigRTKModuleLater(void);
void FactorySettings(void);
void RebootModule(void);
lib/src/main/cpp/rtk_module/virtual_rtk.cpp
@@ -86,7 +86,7 @@
        DEBUG("虚拟平台连接成功");
        virtRtkIsValid = true;
        connectCnt = 0;
//        PlayTTS("模拟器连接", NULL);
        PlayTTS("模拟器连接", NULL);
    } else {
        DEBUG("虚拟平台连接失败");
    }
@@ -110,7 +110,9 @@
                break;
            } else if (lx > 0) {
                RxBufLen += lx;
                const uint8_t *ptr = parseGPS(RxBuf, RxBuf + RxBufLen);
                if(ptr != RxBuf) {
                    memcpy(RxBuf, ptr, RxBufLen - (ptr - RxBuf));
                    RxBufLen -= ptr - RxBuf;
@@ -123,7 +125,9 @@
    }
    if (fd > 0) {
        DEBUG("虚拟平台断开");
        DisconnectTCP(fd);
        PlayTTS("模拟器断开", NULL);
    }
    virtRtkIsValid = false;
@@ -131,7 +135,7 @@
        AppTimer_add(ConnectLater, D_SEC(3));
    }
//    PlayTTS("模拟器断开", NULL);
    DEBUG("虚拟平台线程退出");
    pthread_exit(NULL);
}
lib/src/main/cpp/rtk_platform/parse_net.cpp
@@ -21,7 +21,7 @@
#define DEBUG(fmt, args...)     LOGD("<parse_net> <%s>: " fmt, __func__, ##args)
//#define ENABLE_DEBUG_PROTOCOL
#define ENABLE_DEBUG_PROTOCOL
using namespace std;
lib/src/main/cpp/rtk_platform/platform.cpp
@@ -77,6 +77,8 @@
    struct event_queue_t *next;
} *eventQueue;
static bool mAyDevice = false;
struct platformSocket exceptSocket, currSocket;
static sem_t sem_status_changed;
@@ -113,6 +115,7 @@
static void LoginPlatformTimeout(union sigval sig);
static void TriggerHeartbeat(union sigval sig);
static void RequestRtkNoResp(union sigval sig);
static void AddEvnet(uint32_t event, const uint8_t *data, int length)
{
@@ -181,9 +184,11 @@
        free(p1);
}
void InitPlatform(const uint8_t *phone, const char *domain_name, int port)
void InitPlatform(bool ayDevice, const uint8_t *phone, const char *domain_name, int port)
{
    DEBUG("InitPlatform");
    mAyDevice = ayDevice;
    memset(&gbf, 0, sizeof(gbf));
    memset(&rbf, 0, sizeof(rbf));
@@ -264,7 +269,7 @@
    if (domain_name == NULL || strlen(domain_name) == 0 || port == 0)
        return;
    DEBUG("ConnectPlatform %s: %d", domain_name, port);
    DEBUG("连接RTK平台 %s: %d", domain_name, port);
    // TODO
    struct platformSocketInfo *ptr = (struct platformSocketInfo *)malloc(sizeof(struct platformSocketInfo));
@@ -299,334 +304,371 @@
static void PlatformChangeEntry(uint32_t events, const uint8_t *data, int length)
{
    if (events & PLATFORM_CONNECT_EVT) {
        DEBUG("平台连接成功 %s:%d", currSocket.domain_name, currSocket.port);
        MA_RtkPlatformConnect(1, currSocket.domain_name, currSocket.port);
    switch (events) {
        case PLATFORM_CONNECT_EVT: {
            DEBUG("平台连接成功 %s:%d", currSocket.domain_name, currSocket.port);
            MA_RtkPlatformConnect(1, currSocket.domain_name, currSocket.port);
        platformStatus.connected = 1;
        if (!platformStatus.registed || platformStatus.platformKeyLength == 0) {
            RegisterPlatform();
        } else if (!platformStatus.login) {
            LoginPlatform();
            platformStatus.connected = 1;
            if (!platformStatus.registed || platformStatus.platformKeyLength == 0) {
                RegisterPlatform();
            } else if (!platformStatus.login) {
                LoginPlatform();
            }
            MA_SendBlueStatus("name", "00:1B:35:16:20:4A", 3);
            break;
        }
    }
    if (events & PLATFORM_DISCONNECT_EVT) {
        DEBUG("平台断开 %s:%d", currSocket.domain_name, currSocket.port);
        MA_RtkPlatformConnect(0, currSocket.domain_name, currSocket.port);
        case PLATFORM_DISCONNECT_EVT: {
            DEBUG("平台断开 %s:%d", currSocket.domain_name, currSocket.port);
            MA_RtkPlatformConnect(0, currSocket.domain_name, currSocket.port);
        AppTimer_delete(ConnectPlatformLater);
        AppTimer_add(ConnectPlatformLater, D_SEC(2));
            AppTimer_delete(ConnectPlatformLater);
            AppTimer_add(ConnectPlatformLater, D_SEC(2));
        platformStatus.login = 0;
        platformStatus.connected = 0;
            platformStatus.login = 0;
            platformStatus.connected = 0;
        AppTimer_delete(TriggerHeartbeat);
        AppTimer_delete(RegisterPlatformTimeout);
        AppTimer_delete(LoginPlatformTimeout);
            AppTimer_delete(TriggerHeartbeat);
            AppTimer_delete(RegisterPlatformTimeout);
            AppTimer_delete(LoginPlatformTimeout);
//        PlayTTS("基准源断开", NULL);
    }
    if (events & PLATFORM_REGISTER_EVT) {
        DEBUG("PLATFORM_REGISTER_EVT");
        platformStatus.login = 0;
        if (data[0] == 0) {
            platformStatus.registed = 1;
            platformStatus.platformKeyLength = length - 1;
            memcpy(platformStatus.platformKey, data+1, length-1);
            LoginPlatform();
        } else {
            platformStatus.registed = 0;
            break;
        }
        MA_RtkPlatformRegister(data[0], data + 1, length - 1);
    }
    if (events & PLATFORM_LOGIN_EVT) {
        DEBUG("PLATFORM_LOGIN_EVT");
        case PLATFORM_REGISTER_EVT: {
            DEBUG("平台注册结果:%d", data[0]);
        if (data[0] == 0) {
            platformStatus.login = 1;
            requestPlatformSendRtk = true;
            AppTimer_delete(TriggerHeartbeat);
            AppTimer_add(TriggerHeartbeat, D_SEC(30));
            platformStatus.login = 0;
            if (data[0] == 0) {
                platformStatus.registed = 1;
                platformStatus.platformKeyLength = length - 1;
                memcpy(platformStatus.platformKey, data + 1, length - 1);
                LoginPlatform();
            } else {
                platformStatus.registed = 0;
            }
            MA_RtkPlatformRegister(data[0], data + 1, length - 1);
            break;
        }
        case PLATFORM_LOGIN_EVT: {
            DEBUG("平台登录结果:%d", data[0]);
            if (data[0] == 0) {
                platformStatus.login = 1;
                requestPlatformSendRtk = true;
                AppTimer_delete(TriggerHeartbeat);
                AppTimer_add(TriggerHeartbeat, D_SEC(30));
//            PlayTTS("基准源建立", NULL);
        } else {
            platformStatus.login = 0;
            } else {
                platformStatus.login = 0;
            }
            MA_RtkPlatformLogin(data[0]);
            break;
        }
        MA_RtkPlatformLogin(data[0]);
    }
    if (events & GPS_UPDATE_EVT) {
        DEBUG("GPS_UPDATE_EVT length %d", length);
        const gpsStatus_t *gps = (gpsStatus_t *)data;
        case GPS_UPDATE_EVT: {
            const gpsStatus_t *gps = (gpsStatus_t *) data;
        gbf.qf = gps->gps_status;
        gbf.latitude = gps->latitude;
        gbf.longitude = gps->longitude;
        gbf.altitude = gps->altitude;
        gbf.speed = gps->speed;
        gbf.sat_num = gps->satNum;
        gbf.trackTure = gps->trackTure;
        sprintf(gbf.utc, "%04d%02d%02d%02d%02d%02d.%02d", 2000 + gps->YY, gps->MM, gps->DD, gps->hh, gps->mm, gps->ss, gps->mss);
        if (!strcmp(rbf.utc, gbf.utc)) {
            rbf.sat_num = gbf.sat_num;
            rbf.latitude = gbf.latitude;
            rbf.longitude = gbf.longitude;
            rbf.altitude = gbf.altitude;
            rbf.speed = gbf.speed;
            rbf.trackTure = gbf.trackTure;
            MA_SendRtkBrief(&rbf);
        }
            gbf.qf = gps->gps_status;
            gbf.latitude = gps->latitude;
            gbf.longitude = gps->longitude;
            gbf.altitude = gps->altitude;
            gbf.speed = gps->speed;
            gbf.sat_num = gps->satNum;
            gbf.trackTure = gps->trackTure;
            sprintf(gbf.utc, "%04d%02d%02d%02d%02d%02d.%02d", 2000 + gps->YY, gps->MM, gps->DD,
                    gps->hh, gps->mm, gps->ss, gps->mss);
            if (!strcmp(rbf.utc, gbf.utc)) {
                rbf.sat_num = gbf.sat_num;
                rbf.latitude = gbf.latitude;
                rbf.longitude = gbf.longitude;
                rbf.altitude = gbf.altitude;
                rbf.speed = gbf.speed;
                rbf.trackTure = gbf.trackTure;
                MA_SendRtkBrief(&rbf);
            }
//        MA_SendGpsBrief(&brief);
        RequestRtkDownload(gps, 1);
        DEBUG("GPS_UPDATE_EVT ================");
    }
    if (events & RTK_UPDATE_EVT) {
        DEBUG("RTK_UPDATE_EVT length %d", length);
//        uint32_t ost = AppTimer_GetTickCount();
        const rtk_info *rtk = (rtk_info *)data;
        rbf.qf = rtk->qf;
        rbf.coord_x = rtk->y;
        rbf.coord_y = rtk->x;
        rbf.heading = rtk->heading;
        rbf.pitch = rtk->pitch;
        rbf.roll = rtk->roll;
        rbf.coord_x_dir = 'N';
        rbf.coord_y_dir = 'E';
        sprintf(rbf.utc, "%04d%02d%02d%02d%02d%02d.%02d", 2000 + rtk->YY, rtk->MM, rtk->DD, rtk->hh, rtk->mm, rtk->ss, rtk->dss);
        if (!strcmp(rbf.utc, gbf.utc)) {
            rbf.sat_num = gbf.sat_num;
            rbf.latitude = gbf.latitude;
            rbf.longitude = gbf.longitude;
            rbf.altitude = gbf.altitude;
            rbf.speed = gbf.speed;
            rbf.trackTure = gbf.trackTure;
            MA_SendRtkBrief(&rbf);
            RequestRtkDownload(gps, 1);
            break;
        }
        case RTK_UPDATE_EVT: {
            uint32_t ost = AppTimer_GetTickCount();
            uint32_t ost1 = ost;
        UpdateRTKInfo(rtk);
            const rtk_info *rtk = (rtk_info *) data;
//        DEBUG("driver_test 评判耗时 %ld", AppTimer_GetTickCount() - ost);
            rbf.qf = rtk->qf;
            rbf.coord_x = rtk->y;
            rbf.coord_y = rtk->x;
            rbf.heading = rtk->heading;
            rbf.pitch = rtk->pitch;
            rbf.roll = rtk->roll;
            rbf.coord_x_dir = 'N';
            rbf.coord_y_dir = 'E';
            sprintf(rbf.utc, "%04d%02d%02d%02d%02d%02d.%02d", 2000 + rtk->YY, rtk->MM, rtk->DD,
                    rtk->hh, rtk->mm, rtk->ss, rtk->dss);
            if (!strcmp(rbf.utc, gbf.utc)) {
                rbf.sat_num = gbf.sat_num;
                rbf.latitude = gbf.latitude;
                rbf.longitude = gbf.longitude;
                rbf.altitude = gbf.altitude;
                rbf.speed = gbf.speed;
                rbf.trackTure = gbf.trackTure;
                MA_SendRtkBrief(&rbf);
            }
        DEBUG("RTK_UPDATE_EVT =================");
    }
    if (events & MCU_UPDATE_EVT) {
        DEBUG("MCU_UPDATE_EVT length %d", length);
        // 0-31 version
        // 32-33 selftest
        // 34-35 gpio
        // 36-37 speed
        // 38-39 engine
        // 40-55 sn
        struct mcuBrief brief;
            ost1 = AppTimer_GetTickCount() - ost1;
        memset(&brief, 0, sizeof(brief));
            UpdateRTKInfo(rtk);
        int x = 0;
        while(data[x] != 0 && x < 32) x++;
            ost = AppTimer_GetTickCount() - ost;
        ConvertHex2String(brief.version, data, x);
        brief.selftest = BUILD_UINT16(data[33], data[32]);
            if (ost > 100)
                DEBUG("driver_test 评判耗时 %ld %ld", ost1, ost);
            break;
        }
        case RTK_STATUS_EVT: {
            DEBUG("模块信息 %02X %02X %02X %02X %02X %02X", data[0], data[1], data[2], data[3], data[4], data[5]);
            if (length == 33)
                MA_SendRtkStatus((char *)data, data[32]);
            break;
        }
        case MCU_UPDATE_EVT: {
            // 0-31 version
            // 32-33 selftest
            // 34-35 gpio
            // 36-37 speed
            // 38-39 engine
            // 40-55 sn
            struct mcuBrief brief;
            memset(&brief, 0, sizeof(brief));
            int x = 0;
            while (data[x] != 0 && x < 32) x++;
            ConvertHex2String(brief.version, data, x);
            brief.selftest = BUILD_UINT16(data[33], data[32]);
//        brief.gpio = BUILD_UINT16(data[35], data[34]);
//        brief.speed = BUILD_UINT16(data[37], data[36]);
//        brief.engine = BUILD_UINT16(data[39], data[38]);
//        memcpy(brief.sn, data+40, 16);
        memcpy(brief.sn, data+34, 16);
            memcpy(brief.sn, data + 34, 16);
        MA_SendMcuBrief(&brief);
            MA_SendMcuBrief(&brief);
        if (defaultMcuRom.more > 0) {
            char str[64] = {0};
            if (defaultMcuRom.more > 0) {
                char str[64] = {0};
            memcpy(str, data, 32);
                memcpy(str, data, 32);
            vector<string> ver = split(str, "_");
                vector<string> ver = split(str, "_");
            if (strlen(defaultMcuRom.verCode) > 0 && ver.size() >= 4 && strcmp(defaultMcuRom.verCode, ver[3].c_str()) != 0 && defaultMcuRom.rom != NULL) {
                UploadDfuFile(defaultMcuRom.rom, defaultMcuRom.length);
                delete []defaultMcuRom.rom;
                defaultMcuRom.rom = NULL;
                if (strlen(defaultMcuRom.verCode) > 0 && ver.size() >= 4 &&
                    strcmp(defaultMcuRom.verCode, ver[3].c_str()) != 0 &&
                    defaultMcuRom.rom != NULL) {
                    UploadDfuFile(defaultMcuRom.rom, defaultMcuRom.length);
                    delete[]defaultMcuRom.rom;
                    defaultMcuRom.rom = NULL;
                }
                defaultMcuRom.more = 0;
            }
            defaultMcuRom.more = 0;
        }
//        UpdateSensor(brief.gpio, brief.speed, brief.engine);
    }
    if (events & CAN_UPDATE_EVT) {
        struct canBrief brief;
            break;
        }
        case CAN_UPDATE_EVT: {
            struct canBrief brief;
        brief.gpio = BUILD_UINT16(data[1], data[0]);
        brief.rpm = BUILD_UINT16(data[3], data[2]);
        brief.speed = (double) BUILD_UINT16(data[5], data[4]) / 10.0;
        brief.voltage = (double) BUILD_UINT16(data[7], data[6]) / 10.0;
            brief.gpio = BUILD_UINT16(data[1], data[0]);
            brief.rpm = BUILD_UINT16(data[3], data[2]);
            brief.speed = (double) BUILD_UINT16(data[5], data[4]) / 10.0;
            brief.voltage = (double) BUILD_UINT16(data[7], data[6]) / 10.0;
        MA_SendCanStatus(&brief);
    }
    if (events & CAR_SENSOR_UPDATE_EVT) {
        struct carSensorBrief brief;
        int x = 20;
            MA_SendCanStatus(&brief);
            break;
        }
        case CAR_SENSOR_UPDATE_EVT: {
            struct carSensorBrief brief;
            int x = 20;
        brief.odo = BUILD_UINT32(data[3], data[2], data[1], data[0]);
        brief.trip = BUILD_UINT32(data[7], data[6], data[5], data[4]);
        brief.tripTime = BUILD_UINT32(data[11], data[10], data[9], data[8]);
        brief.cellVolt = ((double) BUILD_UINT16(data[13], data[12])) / 10.0;
        brief.speed = ((double) BUILD_UINT16(data[15], data[14])) / 10.0;
        brief.engine = BUILD_UINT16(data[17], data[16]);
        brief.sas = (short)BUILD_UINT16(data[19], data[18]);
        brief.key = data[x++];
        brief.gear = data[x++];
        brief.aps = data[x++];
        brief.door = data[x++];
        brief.seatBelt = data[x++];
        brief.clutch = data[x++];
        brief.horn = data[x++];
        brief.wiper = data[x++];
        brief.handBreak = data[x++];
        brief.mainBreak = data[x++];
        brief.leftTurnLamp = data[x++];
        brief.rightTurnLamp = data[x++];
        brief.clearanceLamp = data[x++];
        brief.dippedBeamLamp = data[x++];
        brief.mainBeamLamp = data[x++];
        brief.fogLamp = data[x++];
        brief.assBreak = data[x++];
        brief.surround1 = data[x++];
        brief.surround2 = data[x++];
        brief.surround3 = data[x++];
        brief.surround4 = data[x++];
            brief.odo = BUILD_UINT32(data[3], data[2], data[1], data[0]);
            brief.trip = BUILD_UINT32(data[7], data[6], data[5], data[4]);
            brief.tripTime = BUILD_UINT32(data[11], data[10], data[9], data[8]);
            brief.cellVolt = ((double) BUILD_UINT16(data[13], data[12])) / 10.0;
            brief.speed = ((double) BUILD_UINT16(data[15], data[14])) / 10.0;
            brief.engine = BUILD_UINT16(data[17], data[16]);
            brief.sas = (short) BUILD_UINT16(data[19], data[18]);
            brief.key = data[x++];
            brief.gear = data[x++];
            brief.aps = data[x++];
            brief.door = data[x++];
            brief.seatBelt = data[x++];
            brief.clutch = data[x++];
            brief.horn = data[x++];
            brief.wiper = data[x++];
            brief.handBreak = data[x++];
            brief.mainBreak = data[x++];
            brief.leftTurnLamp = data[x++];
            brief.rightTurnLamp = data[x++];
            brief.clearanceLamp = data[x++];
            brief.dippedBeamLamp = data[x++];
            brief.mainBeamLamp = data[x++];
            brief.fogLamp = data[x++];
            brief.assBreak = data[x++];
            brief.surround1 = data[x++];
            brief.surround2 = data[x++];
            brief.surround3 = data[x++];
            brief.surround4 = data[x++];
        MA_SendCarSensorBrief(&brief);
            MA_SendCarSensorBrief(&brief);
        car_sensor_t sensor;
        x = 20;
            car_sensor_t sensor;
            x = 20;
        sensor.odo = BUILD_UINT32(data[3], data[2], data[1], data[0]);
        sensor.trip = BUILD_UINT32(data[7], data[6], data[5], data[4]);
        sensor.tripTime = BUILD_UINT32(data[11], data[10], data[9], data[8]);
        sensor.cellVolt = (double)(BUILD_UINT16(data[13], data[12])) / 10.0;
        sensor.speed = BUILD_UINT16(data[15], data[14]);
        sensor.engine = BUILD_UINT16(data[17], data[16]);
        sensor.sas = (short)BUILD_UINT16(data[19], data[18]);
        sensor.key = data[x++];
        sensor.gear = data[x++];
        sensor.aps = data[x++];
        sensor.door = data[x++];
        sensor.seatBelt = data[x++];
        sensor.clutch = data[x++];
        sensor.horn = data[x++];
        sensor.wiper = data[x++];
        sensor.handBreak = data[x++];
        sensor.mainBreak = data[x++];
        sensor.leftTurnLamp = data[x++];
        sensor.rightTurnLamp = data[x++];
        sensor.clearanceLamp = data[x++];
        sensor.dippedBeamLamp = data[x++];
        sensor.mainBeamLamp = data[x++];
        sensor.fogLamp = data[x++];
        sensor.assBreak = data[x++];
        sensor.surround1 = data[x++];
        sensor.surround2 = data[x++];
        sensor.surround3 = data[x++];
        sensor.surround4 = data[x++];
            sensor.odo = BUILD_UINT32(data[3], data[2], data[1], data[0]);
            sensor.trip = BUILD_UINT32(data[7], data[6], data[5], data[4]);
            sensor.tripTime = BUILD_UINT32(data[11], data[10], data[9], data[8]);
            sensor.cellVolt = (double) (BUILD_UINT16(data[13], data[12])) / 10.0;
            sensor.speed = BUILD_UINT16(data[15], data[14]);
            sensor.engine = BUILD_UINT16(data[17], data[16]);
            sensor.sas = (short) BUILD_UINT16(data[19], data[18]);
            sensor.key = data[x++];
            sensor.gear = data[x++];
            sensor.aps = data[x++];
            sensor.door = data[x++];
            sensor.seatBelt = data[x++];
            sensor.clutch = data[x++];
            sensor.horn = data[x++];
            sensor.wiper = data[x++];
            sensor.handBreak = data[x++];
            sensor.mainBreak = data[x++];
            sensor.leftTurnLamp = data[x++];
            sensor.rightTurnLamp = data[x++];
            sensor.clearanceLamp = data[x++];
            sensor.dippedBeamLamp = data[x++];
            sensor.mainBeamLamp = data[x++];
            sensor.fogLamp = data[x++];
            sensor.assBreak = data[x++];
            sensor.surround1 = data[x++];
            sensor.surround2 = data[x++];
            sensor.surround3 = data[x++];
            sensor.surround4 = data[x++];
        if (sensor.clutch == 1)
            sensor.gear = 0;
            if (sensor.clutch == 1)
                sensor.gear = 0;
        UpdateSensor(&sensor);
    }
    if (events & CARD_UPDATE_EVT) {
        DEBUG("CARD_UPDATE_EVT length %d", length);
            UpdateSensor(&sensor);
            break;
        }
        case CARD_UPDATE_EVT: {
            DEBUG("CARD_UPDATE_EVT length %d", length);
        int ret = -1;
            int ret = -1;
        for (int i = 0; i < length; ++i) {
            if (data[i] != 0) {
                ret = 0;
                break;
            for (int i = 0; i < length; ++i) {
                if (data[i] != 0) {
                    ret = 0;
                    break;
                }
            }
            struct cardBrief brief;
            brief.result = ret;
            ConvertHex2String(brief.card, data, length);
            MA_SendCardBrief(&brief);
            break;
        }
        struct cardBrief brief;
        brief.result = ret;
        ConvertHex2String(brief.card, data, length);
        MA_SendCardBrief(&brief);
    }
    if (events & PLAY_TTS_DONE_EVT) {
        tts_back_t *cb = (tts_back_t *) data;
        if (cb->callback != NULL) {
            cb->callback(cb->seq);
        }
    }
    if (events & MASTER_COMM_EVT) {
        union {
            int a;
            uint8_t b[sizeof(int)];
        } c;
        c.b[0] = data[0];
        c.b[1] = data[1];
        c.b[2] = data[2];
        c.b[3] = data[3];
        if (length == 4)
            MA_MainProcMsgEntry(c.a, NULL);
        else {
            MA_MainProcMsgEntry(c.a, (char *) data + 4);
        }
    }
    if (events & BLUETOOTH_STATUS_EVT) {
        DEBUG("BLUETOOTH_STATUS_EVT");
        uint8_t sta;
        if (length == 128) {
            MA_SendBlueStatus((char *)data, (char *)data+64, 3);
            sta = 3;
        } else if (length == 64) {
            MA_SendBlueStatus(NULL, (char *)data, 3);
            sta = 3;
        } else {
            MA_SendBlueStatus(NULL, NULL, data[0]);
            sta = data[0];
        }
        if (sta == 3) {
            // Connected
            btConnected = true;
            ParseMcuInit();
            ConfigRTKModuleLater();
            PlayTTS("蓝牙连接", NULL);
        } else if (sta == 2) {
            // Disconnect
            btConnected = false;
            PlayTTS("蓝牙断开", NULL);
        } else if (sta == 1) {
            // Open
            btEnable = true;
            if (strlen(btAddr) > 0) {
                ConnectToBluetooth(btAddr, NULL);
        case PLAY_TTS_DONE_EVT: {
            tts_back_t *cb = (tts_back_t *) data;
            if (cb->callback != NULL) {
                cb->callback(cb->seq);
            }
            break;
        }
        case MASTER_COMM_EVT: {
            union {
                int a;
                uint8_t b[sizeof(int)];
            } c;
            c.b[0] = data[0];
            c.b[1] = data[1];
            c.b[2] = data[2];
            c.b[3] = data[3];
            if (length == 4)
                MA_MainProcMsgEntry(c.a, NULL);
            else {
                MA_MainProcMsgEntry(c.a, (char *) data + 4);
            }
            break;
        }
        case BLUETOOTH_STATUS_EVT: {
            DEBUG("BLUETOOTH_STATUS_EVT");
            if (!mAyDevice) {
                uint8_t sta;
                if (length == 128) {
                    MA_SendBlueStatus((char *) data, (char *) data + 64, 3);
                    sta = 3;
                } else if (length == 64) {
                    MA_SendBlueStatus(NULL, (char *) data, 3);
                    sta = 3;
                } else {
                    MA_SendBlueStatus(NULL, NULL, data[0]);
                    sta = data[0];
                }
                if (sta == 3) {
                    // Connected
                    btConnected = true;
                    ParseMcuInit();
                    ConfigRTKModuleLater();
                    PlayTTS("蓝牙连接", NULL);
                } else if (sta == 2) {
                    // Disconnect
                    if (btConnected) {
                        btConnected = false;
                        PlayTTS("蓝牙断开", NULL);
                    }
                } else if (sta == 1) {
                    // Open
                    btEnable = true;
                    if (strlen(btAddr) > 0) {
                        ConnectToBluetooth(btAddr, NULL);
                    }
//            ConnectToBluetooth("00:1B:35:16:20:4A", NULL);
//            ConnectToBluetooth("00:1B:35:16:20:4A", "3800");``
//            ConnectToBluetooth("00:1D:43:9A:E0:79", "1900");
//            ConnectToBluetooth("DESKTOP-IE9V7U8", "0000");
            PlayTTS("蓝牙启动", NULL);
        } else {
            // Close
            btEnable = false;
            btConnected = false;
            PlayTTS("蓝牙关闭", NULL);
                    PlayTTS("蓝牙启动", NULL);
                } else {
                    // Close
                    btEnable = false;
                    btConnected = false;
                    PlayTTS("蓝牙关闭", NULL);
                }
            }
            break;
        }
    }
    if (events & BLUETOOTH_DATA_EVT) {
        ParseMcu(data, length);
        case BLUETOOTH_DATA_EVT: {
            ParseMcu(data, length);
            break;
        }
        case SENSOR_CHANGE_EVT: {
            SensorXChanged(BUILD_UINT16(data[1], data[0]), BUILD_UINT32(data[5], data[4], data[3], data[2]));
            break;
        }
        default:
            break;
    }
}
@@ -706,13 +748,14 @@
static void RegisterPlatformTimeout(union sigval sig)
{
    DEBUG("RegisterPlatformTimeout");
    DEBUG("RTK平台注册超时");
    AppTimer_delete(RegisterPlatformTimeout);
    RegisterPlatform();
}
static void RegisterPlatform(void)
{
    DEBUG("RTK平台注册...");
    AppTimer_delete(RegisterPlatformTimeout);
    AppTimer_add(RegisterPlatformTimeout, D_SEC(15));
    SendDeviceRegister(deviceInfo.province, deviceInfo.city, deviceInfo.device_model,
@@ -730,12 +773,14 @@
static void LoginPlatformTimeout(union sigval sig)
{
    DEBUG("RTK平台登录超时");
    AppTimer_delete(LoginPlatformTimeout);
    LoginPlatform();
}
static void LoginPlatform(void)
{
    DEBUG("RTK平台登录...");
    uint32_t tim = time(NULL);
    uint8_t data[12];
    uint8_t *ciphertext;
@@ -748,6 +793,7 @@
    AppTimer_delete(LoginPlatformTimeout);
    AppTimer_add(LoginPlatformTimeout, D_SEC(15));
    DESEncrypt(platformStatus.platformKey, platformStatus.platformKeyLength, data, 4, &ciphertext);
    if (ciphertext != NULL) {
lib/src/main/cpp/rtk_platform/platform.h
@@ -7,20 +7,24 @@
#include "../rtk_module/rtk.h"
#define PLATFORM_CONNECT_EVT                         0x0001
#define PLATFORM_DISCONNECT_EVT                      0x0002
#define PLATFORM_REGISTER_EVT                        0x0004
#define PLATFORM_LOGIN_EVT                           0x0008
#define RTK_UPDATE_EVT                               0x0010
#define GPS_UPDATE_EVT                              0x0020
#define MCU_UPDATE_EVT                              0x0040
#define CARD_UPDATE_EVT                             0x0080
#define PLAY_TTS_DONE_EVT                           0x0100
#define CAR_SENSOR_UPDATE_EVT                       0x0200
#define MASTER_COMM_EVT                             0x0400
#define CAN_UPDATE_EVT                              0x0800
#define BLUETOOTH_DATA_EVT                          0x1000
#define BLUETOOTH_STATUS_EVT                        0x2000
enum {
    PLATFORM_CONNECT_EVT,
    PLATFORM_DISCONNECT_EVT,
    PLATFORM_REGISTER_EVT,
    PLATFORM_LOGIN_EVT,
    RTK_UPDATE_EVT,
    RTK_STATUS_EVT,
    GPS_UPDATE_EVT,
    MCU_UPDATE_EVT,
    CARD_UPDATE_EVT,
    PLAY_TTS_DONE_EVT,
    CAR_SENSOR_UPDATE_EVT,
    MASTER_COMM_EVT,
    CAN_UPDATE_EVT,
    BLUETOOTH_DATA_EVT,
    BLUETOOTH_STATUS_EVT,
    SENSOR_CHANGE_EVT
};
typedef struct {
    char domain_name[32];
@@ -36,7 +40,7 @@
    int rtk_interval;
} rtk_platform_cfg_t;
void InitPlatform(const uint8_t *phone, const char *domain_name, int port);
void InitPlatform(bool ayDevice, const uint8_t *phone, const char *domain_name, int port);
void ConfigPlatform(const rtk_platform_cfg_t *p);
void PlatformStatusChanged(uint32_t event, const uint8_t *data, int length);
lib/src/main/cpp/test_common/car_sensor.cpp
@@ -8,6 +8,7 @@
#include "../defs.h"
#include "../common/apptimer.h"
#include "../jni_log.h"
#include "../rtk_platform/platform.h"
#define DEBUG(fmt, args...)     LOGD("<car_sensor> <%s>: " fmt, __func__, ##args)
@@ -229,6 +230,19 @@
    pthread_mutex_lock(&status_rw_mutex);
    CarStatus[id] = value;
    pthread_mutex_unlock(&status_rw_mutex);
    if (id != OBD_SPEED && id != ENGINE_RPM) {
        uint8_t buffer[6];
        buffer[0] = HI_UINT16(id);
        buffer[1] = LO_UINT16(id);
        buffer[2] = BREAK_UINT32(value, 3);
        buffer[3] = BREAK_UINT32(value, 2);
        buffer[4] = BREAK_UINT32(value, 1);
        buffer[5] = BREAK_UINT32(value, 0);
        PlatformStatusChanged(SENSOR_CHANGE_EVT, buffer, 6);
    }
}
static void LRLightTimeout(union sigval sig)
@@ -267,7 +281,6 @@
static void SensorChanged(int id, int value)
{
//    DEBUG("状态改变 %d = %d", id, value);
    switch (id) {
        case SENSOR_LEFT_TURN_SIGNAL: {
            left_turn_signal = value;
@@ -432,7 +445,7 @@
//            break;
//        }
        default:
            break;
            return;
    }
}
lib/src/main/cpp/test_items/driving_curve.cpp
@@ -105,7 +105,7 @@
        if (!crashRedLine) {
            crashRedLine = true;
            // 车轮压边线,不合格
            AddExamFault(27, rtkTime);
            AddExamFault(20601, rtkTime);
            DEBUG("车轮压边线");
            if (who == 1) {
                PlayTTS("压左曲线", NULL);
@@ -132,7 +132,7 @@
        if (tp - stopTimepoint >= CorrectPauseCriteria(examParam.curve_pause_criteria) && !reportStopCarTimeout) {
            // 停车超2秒,不合格
            AddExamFault(28, rtkTime);
            AddExamFault(20602, rtkTime);
            DEBUG("中途停车");
            reportStopCarTimeout = true;
        }
lib/src/main/cpp/test_items/park_bottom.cpp
@@ -85,7 +85,7 @@
        if ((parkStatus[0] != 1 || parkStatus[1] != 1) && !reportParkFail && reverseCar) {
            // 倒库不入,不合格
            reportParkFail = true;
            AddExamFault(8, rtkTime);
            AddExamFault(20103, rtkTime);
            DEBUG("倒库不入");
        }
        goto TEST_END;
@@ -111,7 +111,7 @@
        if (!occurCrashRedLine && reverseCar) {
            occurCrashRedLine = true;
            // 车身出线,不合格
            AddExamFault(7, rtkTime);
            AddExamFault(10116, rtkTime);
            DEBUG("车轮压线");
            if (who == 1) {
                PlayTTS("压左库位线", NULL);
@@ -131,14 +131,14 @@
        } else if (parkCount == 1) {
            if (carray[0] == crossCtrlLine) {
                // 不按规定线路,顺序形式,不合格
                AddExamFault(6, rtkTime);
                AddExamFault(20101, rtkTime);
                DEBUG("不按规定线路,顺序形式");
            }
            carray[1] = crossCtrlLine;
        } else if (parkCount == 2) {
            if (carray[0] != crossCtrlLine) {
                // 不按规定线路,顺序形式,不合格
                AddExamFault(6, rtkTime);
                AddExamFault(20101, rtkTime);
                DEBUG("不按规定线路,顺序形式");
            } else {
                // 离开测试区,停止计时
@@ -154,7 +154,7 @@
        // 完成超时,不合格
        if (!reportExamTimeout) {
            reportExamTimeout = true;
            AddExamFault(10, rtkTime);
            AddExamFault(20105, rtkTime);
            DEBUG("项目超时");
        }
    }
@@ -177,7 +177,7 @@
                // 同方向再启动,继续判断是否停车超时
                if (tp - stopTimepoint >= CorrectPauseCriteria(examParam.park_bottom_pause_criteria) && reverseCar) {
                    // 停车超2秒,每次扣5分
                    AddExamFault(11, rtkTime);
                    AddExamFault(20106, rtkTime);
                    DEBUG("中途停车");
                }
            } else if (moveDirect == -1) {
@@ -189,7 +189,7 @@
                if (darray[parkCount] == 0) {
                    if (!crossCtrlLineSw) {
                        // 倒车前,前轮未驶过控制线
                        AddExamFault(9, rtkTime);
                        AddExamFault(20104, rtkTime);
                        DEBUG("倒车前,前轮未驶过控制线");
                    }
                    darray[parkCount] = 1;
@@ -204,7 +204,7 @@
                        if (parkStatus[parkCount] != 1) {
                            // 倒库不入,不合格
                            reportParkFail = true;
                            AddExamFault(8, rtkTime);
                            AddExamFault(20103, rtkTime);
                            DEBUG("倒库不入");
                        }
                    }
@@ -222,7 +222,7 @@
            // 切换为倒车
            if (!crossCtrlLineSw) {
                // 倒车前,前轮未驶过控制线
                AddExamFault(9, rtkTime);
                AddExamFault(20104, rtkTime);
                DEBUG("倒车前,前轮未驶过控制线");
            }
            darray[parkCount] = 1;
lib/src/main/cpp/test_items/park_edge.cpp
@@ -71,7 +71,7 @@
    if (CrashRedLine1(map, car)) {
        if (!occurCrashRedLine1 && occurMoveBack) {
            // 车轮压边线,每次扣10分
            AddExamFault(23, rtkTime);
            AddExamFault(20403, rtkTime);
            DEBUG("车轮压边线");
            occurCrashRedLine1 = true;
        }
@@ -82,7 +82,7 @@
    if (CrashRedLine2(map, car)) {
        if (!occurCrashRedLine2 && occurMoveBack) {
            // 车身压库位线,每次扣10分
            AddExamFault(24, rtkTime);
            AddExamFault(20404, rtkTime);
            DEBUG("车身压库位线");
            occurCrashRedLine2 = true;
        }
@@ -93,9 +93,9 @@
    if (ExitParkArea(map, car) || ExitParkArea2(map, car)) {
        if (!parkSuccess && occurMoveBack && !reportParkFail) {
            // 直接驶离测试区,认为移库不入
            AddExamFault(21, rtkTime);
            AddExamFault(10103, rtkTime);
            reportParkFail = true;
            DEBUG("直接驶离测试区,移库不入");
            DEBUG("直接驶离测试区,不按考试员指令驾驶");
        }
        testing = false;
        goto TEST_END;
@@ -122,7 +122,7 @@
        if (!reportExamTimeout && tp - moveBackTimePoint >= examParam.park_edge_limit_time) {
            // 超时90秒,不合格
            AddExamFault(22, rtkTime);
            AddExamFault(20402, rtkTime);
            reportExamTimeout = true;
            DEBUG("移库90秒超时");
        }
@@ -145,7 +145,7 @@
                // 同方向再启动,继续判断是否停车超时
                if (tp - stopTimepoint >= CorrectPauseCriteria(examParam.park_edge_pause_criteria) && occurMoveBack) {
                    // 停车超2秒,每次扣5分
                    AddExamFault(26, rtkTime);
                    AddExamFault(20406, rtkTime);
                    DEBUG("停车超时");
                }
            } else {
@@ -160,7 +160,7 @@
                    if (!parkSuccess && !reportParkFail) {
                        // 停止后,车身出线,不合格
                        AddExamFault(21, rtkTime);
                        AddExamFault(20401, rtkTime);
                        reportParkFail = true;
                        DEBUG("移库不入");
                    }
@@ -168,7 +168,7 @@
                    // 在这里检查转向灯状态
                    if (ReadCarStatus(TURN_SIGNAL_LAMP) != LEFT_TURN_LIGHT) {
                        // 不开转向灯,扣10分
                        AddExamFault(25, rtkTime);
                        AddExamFault(20405, rtkTime);
                        DEBUG("未开启转向灯");
                    }
                }
lib/src/main/cpp/test_items/stop_and_start.cpp
@@ -71,7 +71,7 @@
    if (CrashRedLine(map, car)) {
        // 车轮压线,不合格
        if (!occurCrashRedLine) {
            AddExamFault(13, rtkTime);
            AddExamFault(10116, rtkTime);
            DEBUG("车轮压线");
        }
        occurCrashRedLine = true;
@@ -102,7 +102,7 @@
        } else if (stopCar && !handBreakActive) {
            // 检查是否拉住手刹
            handBreakActive = true;
            AddExamFault(19, rtkTime);
            AddExamFault(20306, rtkTime);
            DEBUG("没拉手刹");
        }
        prevMoveDirect = moveDirect;
@@ -123,21 +123,21 @@
            if (dis1 > examParam.ramp_stoppoint_red_distance) {
                // 距离停止线前后超出50厘米
                AddExamFault(12, rtkTime);
                AddExamFault(20301, rtkTime);
                DEBUG("距离停止线前后超出50厘米,不合格");
            } else if (fabs(dis1) > EPSILON) {
                // 前保险没有位于停止带内,但没有超出50厘米,扣10分
                AddExamFault(17, rtkTime);
                AddExamFault(20304, rtkTime);
                DEBUG("前保险没有位于停止带内,但没有超出50厘米");
            }
            if (dis2 > examParam.ramp_edge_red_distance) {
                // 距离边线超出50厘米,不合格
                AddExamFault(14, rtkTime);
                AddExamFault(20302, rtkTime);
                DEBUG("距离边线超出50厘米");
            } else if (dis2 > examParam.ramp_edge_yellow_distance) {
                // 距离边线超出30厘米,扣10分
                AddExamFault(18, rtkTime);
                AddExamFault(20305, rtkTime);
                DEBUG("距离边线超出30厘米");
            }
        }
@@ -159,7 +159,7 @@
            if (slideDistance > examParam.ramp_slide_red_distance && !slideLongDistance && !reportSlideFault) {
                // 后滑超过30厘米, 不合格
                AddExamFault(16, rtkTime);
                AddExamFault(10106, rtkTime);
                DEBUG("后滑超过30厘米");
                slideLongDistance = true;
                reportSlideFault = true;
@@ -171,7 +171,7 @@
                DistanceOf(stopPoint, car->carXY[car->axial[AXIAL_FRONT]]) < 0.1)) {
            if (TimeMakeComposite(rtkTime->hh, rtkTime->mm, rtkTime->ss, rtkTime->mss*10) - stopCarTime > examParam.ramp_start_car_limit_time) {
                // 起步时间超过30秒,不合格
                AddExamFault(15, rtkTime);
                AddExamFault(20303, rtkTime);
                DEBUG("起步时间超过30秒");
                reportStartTimeout = true;
            }
@@ -182,7 +182,7 @@
            if (slideNormalDistance && !slideLongDistance && !reportSlideFault) {
                reportSlideFault = true;
                // 后滑超过10厘米,但没超过30厘米
                AddExamFault(20, rtkTime);
                AddExamFault(10204, rtkTime);
                DEBUG("后滑超过10厘米,但没超过30厘米");
            }
        }
lib/src/main/cpp/test_items/turn_a90.cpp
@@ -79,7 +79,7 @@
        if (!crashRedLine) {
            crashRedLine = true;
            // 碾压道路边缘,不合格
            AddExamFault(29, rtkTime);
            AddExamFault(20701, rtkTime);
            DEBUG("碾压道路边缘");
        }
    } else {
@@ -101,7 +101,7 @@
        if (tp - stopTimepoint >= CorrectPauseCriteria(examParam.turn_a90_pause_criteria) && !reportStopCarTimeout) {
            // 停车超2秒,每次扣5分
            AddExamFault(31, rtkTime);
            AddExamFault(20703, rtkTime);
            DEBUG("中途停车");
            reportStopCarTimeout = true;
        }
@@ -128,7 +128,7 @@
            if ((turn_direct == 'R' && ReadCarStatus(TURN_SIGNAL_LAMP) != RIGHT_TURN_LIGHT) ||
                    (turn_direct == 'L' && ReadCarStatus(TURN_SIGNAL_LAMP) != LEFT_TURN_LIGHT)) {
                DEBUG("转向灯未开启");
                AddExamFault(30, rtkTime);
                AddExamFault(20702, rtkTime);
            }
        }
        turnLeftFinished = true;
lib/src/main/cpp/test_items2/car_start.cpp
@@ -48,11 +48,11 @@
            if (sensor.value != LEFT_TURN_LIGHT) {
                DEBUG("变调未打灯!!");
                // 没打灯,不合格
                AddExamFault(13, rtkTime);
                AddExamFault(30121, rtkTime);
            } else if (TimeGetDiff(rtkTime, &sensor.time) < D_SEC(3)) {
                DEBUG("转向灯时间不足");
                // 不足3秒,不合格
                AddExamFault(14, rtkTime);
                AddExamFault(30122, rtkTime);
            }
        }
    }
@@ -63,11 +63,11 @@
        if (sensor.name == HAND_BREAK && sensor.value == BREAK_ACTIVE) {
            DEBUG("Handbreak active move over 10m");
            // 手刹拉起状态下,行驶了10米以上,不合格
            AddExamFault(25, rtkTime);
            AddExamFault(40205, rtkTime);
        } else if (handBreakActive) {
            // 手刹拉起状态下,行驶了1米以上,扣10分
            DEBUG("Handbreak active move over 1M");
            AddExamFault(26, rtkTime);
            AddExamFault(40206, rtkTime);
        }
        PlayTTS(examParam.start_car_end_tts, NULL);
@@ -82,7 +82,7 @@
            if (sensor.name == DOOR && sensor.value == DOOR_OPEN) {
                // 车门未完全关闭,不合格
                DEBUG("车门未关闭");
                AddExamFault(23, rtkTime);
                AddExamFault(40202, rtkTime);
            }
            sensor = ReadCarSensorValue(HAND_BREAK);
@@ -95,7 +95,7 @@
    if (ReadCarStatus(ENGINE_RPM) > examParam.start_car_max_rpm && !checkEngineRPM) {
        // 转速超标,不合格
        DEBUG("转速超标");
        AddExamFault(29, rtkTime);
        AddExamFault(40210, rtkTime);
        checkEngineRPM = true;
    }
lib/src/main/cpp/test_items2/change_lane.cpp
@@ -43,7 +43,7 @@
    if (ReadOdo() - maxMoveDistance > examParam.change_lane_limit_distance) {
        // 超车未完成
        DEBUG("变道固定距离内未完成 当前里程 %f", ReadOdo());
        AddExamFault(3, rtkTime);
        AddExamFault(30103, rtkTime);
        return false;
    }
lib/src/main/cpp/test_items2/drive_straight.cpp
@@ -80,7 +80,7 @@
        if (fabs(offset2 - offsetBase) > examParam.straight_max_offset) {
            DEBUG("直线偏移大于30厘米 offset2 = %f", fabs(offset2 - offsetBase));
            // 偏移大于30厘米,不合格
            AddExamFault(30, rtkTime);
            AddExamFault(40301, rtkTime);
            return false;
        }
    }
lib/src/main/cpp/test_items2/dummy_light.cpp
@@ -11,206 +11,123 @@
#define DEBUG(fmt, args...)     LOGD("<road_exam dummy_light> <%s>: " fmt, __func__, ##args)
enum {
    TTS_NOT_START,
    TTS_DOING,
    TTS_DONE,
    WAIT_OPERATE,
    CHECK_OPERATE
};
static struct RtkTime currRtkTime;
static struct dummy_light_exam *content;
static int contentNum;
static int checkCnt;
static bool turn_left_active, flash_beam_active;
static int question;
static int examTtsSeq = 0;
static vector<int> process;
static bool testing;
static void DummyLightCheckActive(union sigval sig);
static void ExamDummyLight(union sigval sig);
static void CheckSolution(union sigval sig);
static void ExamDummyLight(void);
void StartDummyLightExam(struct dummy_light_exam *ptr, int num, const struct RtkTime* rtkTime)
{
    DEBUG("StartDummyLightExam");
    content = ptr;
    contentNum = num;
    question = 0;
    if (content != NULL && num > 0) {
        DEBUG("启动灯光");
        currRtkTime = *rtkTime;
        for (int i = 0; i < contentNum; ++i) {
            content[i].itemStatus = TTS_NOT_START;
            DEBUG("灯光项目 <%d> item %d, TTS %s", i, content[i].item, content[i].tts);
            DEBUG("灯光项目 <%d> item %d, TTS %s", i, content[i].item, content[i].tts.c_str());
        }
        testing = true;
        AppTimer_delete(DummyLightCheckActive);
        AppTimer_delete(ExamDummyLight);
        AppTimer_add(ExamDummyLight, D_SEC(2));
        AppTimer_delete(CheckSolution);
        ExamDummyLight();
    } else {
        testing = false;
    }
}
int ExecuteDummyLightExam(const struct RtkTime* rtkTime)
bool ExecuteDummyLightExam(const struct RtkTime* rtkTime)
{
    currRtkTime = *rtkTime;
    return (testing)?1:2;
    return testing;
}
void DummyLightTTSDone(int id)
{
    // 等语音播报完毕后计时
    if (id == examTtsSeq && testing) {
    if (testing) {
        vector<int>().swap(process);
        for (int i = 0; i < contentNum; ++i) {
            if (content[i].itemStatus == TTS_DOING) {
                DEBUG("DummyLightTTSDone item %d", content[i].item);
                content[i].itemStatus = TTS_DONE;
                break;
        // 预读取有中间操作步骤的灯光
        for (int i = 0; i < content[question].process.size(); ++i) {
            if (ReadCarStatus((content[question].process[i]>>8) & 0xFF) == content[question].process[i] & 0xFF) {
                process.push_back(content[question].process[i]);
            }
        }
        AppTimer_add(ExamDummyLight, 100);
        AppTimer_delete(CheckSolution);
        AppTimer_add(CheckSolution, D_SEC(5));
    }
}
void TerminateDummyLightExam(void)
{
    testing = false;
    AppTimer_delete(DummyLightCheckActive);
    AppTimer_delete(ExamDummyLight);
    AppTimer_delete(CheckSolution);
}
static void DummyLightCheckActive(union sigval sig)
void handleLigthExam(uint16_t id, int value)
{
    int active = sig.sival_int;
    AppTimer_delete(DummyLightCheckActive);
    DEBUG("DummyLightCheckActive item = %d", active);
    if (testing) {
        for (int i = 0; i < content[question].process.size(); ++i) {
            if (id == ((content[question].process[i] >> 8) & 0xFF) && value == (content[question].process[i] & 0xFF)) {
                if (process.size() == 0 || process.back() != content[question].process[i]) {
                    process.push_back(content[question].process[i]);
                }
            }
        }
    }
}
    switch (active) {
        case DRIVE_AT_NIGHT:
        case TURN_ON_MAIN_BEAM_LAMP:
            if (ReadCarStatus(MAIN_BEAM_LAMP) != MAIN_BEAM_LIGHT) {
                AddExamFault(58, &currRtkTime);
            }
            break;
        case TURN_ON_DIPPED_LAMP:
        case BRIDGE_MEET_CAR:
        case FOLLOW_CAR:
            if (ReadCarStatus(DIPPED_BEAM_LAMP) != DIPPED_BEAM_LIGHT) {
                AddExamFault(58, &currRtkTime);
            }
            break;
        case DRIVE_IN_FOG:
            if (ReadCarStatus(FOG_LAMP) != FOG_LIGHT) {
                AddExamFault(58, &currRtkTime);
            }
            break;
        case THROUGE_CROSSWALK:
        case THROUGE_CURVE:
        case THROUGE_CROSSROADS:
            if (++checkCnt < 5) {
                if (ReadCarStatus(FLASH_BEAM_LAMP) == FLASH_BEAM_LIGHT) {
                    flash_beam_active = true;
                }
                AppTimer_add(DummyLightCheckActive, D_SEC(1), active);
                return;
            } else {
                if (!flash_beam_active) {
                    AddExamFault(58, &currRtkTime);
static void CheckSolution(union sigval sig)
{
    int question = sig.sival_int;
    AppTimer_delete(CheckSolution);
    if (content[question].process.size() > 0) {
        if (content[question].process.size() != process.size()) {
            AddExamFault(content[question].wrongCode, &currRtkTime);
            goto NEXT_LIGHT;
        } else {
            // 操作顺序也要满足
            for (int i = 0; i < content[question].process.size(); ++i) {
                if (process[i] != content[question].process[i]) {
                    AddExamFault(content[question].wrongCode, &currRtkTime);
                    goto NEXT_LIGHT;
                }
            }
            break;
        case OVERTAKE:
            if (++checkCnt < 5) {
                if (!flash_beam_active) {
                    if (ReadCarStatus(TURN_SIGNAL_LAMP) == LEFT_TURN_LIGHT) {
                        turn_left_active = true;
                    }
                }
                if (turn_left_active) {
                    if (ReadCarStatus(FLASH_BEAM_LAMP) == FLASH_BEAM_LIGHT) {
                        flash_beam_active = true;
                    }
                }
                AppTimer_add(DummyLightCheckActive, D_SEC(1), OVERTAKE);
                return;
            } else {
                if (!flash_beam_active || !turn_left_active) {
                    AddExamFault(58, &currRtkTime);
                }
            }
            break;
        case CAR_FAULT:
        case PARK_CAR_TEMP:
            if (ReadCarStatus(TURN_SIGNAL_LAMP) != HAZARD_LIGHTS) {
                AddExamFault(58, &currRtkTime);
            }
            break;
        default:
            break;
        }
    }
    for (int i = 0; i < contentNum; ++i) {
        if (content[i].item == active) {
            content[i].itemStatus = CHECK_OPERATE;
    for (int i = 0; i < content[question].solution.size(); ++i) {
        if (ReadCarStatus((content[question].solution[i]>>8)&0xFF) != content[question].solution[i] & 0xFF) {
            AddExamFault(content[question].wrongCode, &currRtkTime);
            break;
        }
    }
    AppTimer_add(ExamDummyLight, 500);
NEXT_LIGHT:
    question++;
    ExamDummyLight();
}
static void ExamDummyLight(union sigval sig)
static void ExamDummyLight(void)
{
    int i = 0;
    AppTimer_delete(ExamDummyLight);
    for (; i < contentNum; ++i) {
        switch (content[i].itemStatus) {
            case TTS_NOT_START:
                DEBUG("提示语言 %d: %s", content[i].item, content[i].tts);
                content[i].itemStatus = TTS_DOING;
                examTtsSeq = PlayTTS(content[i].tts, DummyLightTTSDone);
                // 等待TTS播放完毕
                return;
            case TTS_DOING:
                return;
            case TTS_DONE:
                content[i].itemStatus = WAIT_OPERATE;
                AppTimer_delete(DummyLightCheckActive);
                DEBUG("提示语言完毕 %d", content[i].item);
                if (content[i].item == OVERTAKE) {
                    checkCnt = 0;
                    turn_left_active = flash_beam_active = false;
                    AppTimer_add(DummyLightCheckActive, D_SEC(1), content[i].item);
                } else if (content[i].item == THROUGE_CROSSWALK || content[i].item == THROUGE_CURVE || content[i].item == THROUGE_CROSSROADS) {
                    checkCnt = 0;
                    flash_beam_active = false;
                    AppTimer_add(DummyLightCheckActive, D_SEC(1), content[i].item);
                } else if (content[i].item >= 100)
                    AppTimer_add(DummyLightCheckActive, D_SEC(3), content[i].item);
                else
                    AppTimer_add(DummyLightCheckActive, D_SEC(5), content[i].item);
                return;
            case WAIT_OPERATE:
                return;
            case CHECK_OPERATE:
            default:
                break;
        }
    }
    if (i >= contentNum) {
    if (testing && question < contentNum) {
        PlayTTS(content[question].tts, DummyLightTTSDone);
    } else {
        testing = false;
    }
}
lib/src/main/cpp/test_items2/dummy_light.h
@@ -6,6 +6,8 @@
#define MYAPPLICATION2_DUMMY_LIGHT_H
#include "../driver_test.h"
#include <vector>
#include <string>
enum {
    TURN_ON_DIPPED_LAMP = 1,
@@ -24,13 +26,16 @@
struct dummy_light_exam {
    int item;
    int itemStatus;
    char tts[512];
    int wrongCode;
    std::vector<int> process;
    std::vector<int> solution;
    std::string tts;
};
void StartDummyLightExam(struct dummy_light_exam *ptr, int num, const struct RtkTime* rtkTime);
int ExecuteDummyLightExam(const struct RtkTime* rtkTime);
bool ExecuteDummyLightExam(const struct RtkTime* rtkTime);
void DummyLightTTSDone(int id);
void TerminateDummyLightExam(void);
void handleLigthExam(uint16_t id, int value);
#endif //MYAPPLICATION2_DUMMY_LIGHT_H
lib/src/main/cpp/test_items2/operate_gear.cpp
@@ -94,7 +94,7 @@
        } else if (sensor.value != expectGear) {
            // 未按指令操作挡位,不合格
            DEBUG("首次换挡错误 GEAR %d  希望 %d", sensor.value, expectGear);
            AddExamFault(31, rtkTime);
            AddExamFault(40401, rtkTime);
            return false;
        } else {
            // 在此挡位行驶一定距离,再执行下一个
@@ -121,7 +121,7 @@
        } else if (sensor.value != expectGear) {
            // 未按指令操作挡位,不合格
            DEBUG("二次换挡错误 GEAR %d  希望 %d", sensor.value, expectGear);
            AddExamFault(31, rtkTime);
            AddExamFault(40401, rtkTime);
            return false;
        } else {
            // 在此挡位行驶一定距离,再执行下一个
@@ -140,7 +140,7 @@
    if (ReadOdo() - maxMoveDistance > 120) {
        // 未按指令操作挡位,不合格
        DEBUG("未按指令操作挡位,超时");
        AddExamFault(31, rtkTime);
        AddExamFault(40401, rtkTime);
        return false;
    }
lib/src/main/cpp/test_items2/overtake.cpp
@@ -44,7 +44,7 @@
            originalLane = currLane;
        } else {
            DEBUG("右侧超车");
            AddExamFault(3, rtkTime);
            AddExamFault(30103, rtkTime);
            return false;
        }
    } else if (setup == 2) {
@@ -55,7 +55,7 @@
            return false;
        } else {
            DEBUG("超车违规变道");
            AddExamFault(3, rtkTime);
            AddExamFault(30103, rtkTime);
            return false;
        }
    }
@@ -63,7 +63,7 @@
    if (ReadOdo() - maxMoveDistance > examParam.overtake_limit_distance) {
        // 超车未完成
        DEBUG("超车固定距离内未完成 当前里程 %f", ReadOdo());
        AddExamFault(3, rtkTime);
        AddExamFault(30103, rtkTime);
        return false;
    }
lib/src/main/cpp/test_items2/prepare.cpp
New file
@@ -0,0 +1,100 @@
//
// Created by YY on 2020/12/16.
//
#include "prepare.h"
#include "../native-lib.h"
#include "../driver_test.h"
#include "../test_common/car_sensor.h"
#include "../common/apptimer.h"
#include "../jni_log.h"
#define DEBUG(fmt, args...)     LOGD("<prepare> <%s>: " fmt, __func__, ##args)
static int touch[4];
static int hint_cnt;
static bool exec = false;
static void TtsBack(int seq);
static void PrepareTimeout(union sigval sig);
static void PrepareTimeout2(union sigval sig);
void StartPrepare(void)
{
    exec = true;
    hint_cnt = 0;
    memset(touch, 0, sizeof(touch));
    PlayTTS(examParam.prepare_tts, TtsBack);
    DEBUG("开始上车准备");
}
void handlePrepare(uint16_t sensor_id, int value)
{
    if (!exec)
        return;
    if (sensor_id == SEATBELT) {
        if (value == INSERT_SEATBELT) {
            AppTimer_delete(PrepareTimeout);
            // 检查绕车传感器情况
            if (touch[0] + touch[1] + touch[2] + touch[3] != 4) {
                exec = false;
                PrepareOver(-1);
            } else {
                exec = false;
                PrepareOver(0);
            }
        } else {
            // 安全带解开
            AppTimer_delete(PrepareTimeout2);
        }
    }
    if (sensor_id == SURROUND_CAR_1 && value == SURROUND_CAR_ACTIVE && touch[0] != 1) {
        touch[0] = 1;
        PlayTTS(examParam.touch_leftfront_tts, NULL);
        DEBUG("触摸传感器1");
    }
    if (sensor_id == SURROUND_CAR_2 && value == SURROUND_CAR_ACTIVE && touch[1] != 1) {
        touch[1] = 1;
        PlayTTS(examParam.touch_leftrear_tts, NULL);
        DEBUG("触摸传感器2");
    }
    if (sensor_id == SURROUND_CAR_3 && value == SURROUND_CAR_ACTIVE && touch[2] != 1) {
        touch[2] = 1;
        PlayTTS(examParam.touch_rightrear_tts, NULL);
        DEBUG("触摸传感器3");
    }
    if (sensor_id == SURROUND_CAR_4 && value == SURROUND_CAR_ACTIVE && touch[3] != 1) {
        touch[3] = 1;
        PlayTTS(examParam.touch_rightfront_tts, NULL);
        DEBUG("触摸传感器4");
    }
}
static void TtsBack(int seq)
{
    if (hint_cnt == 0) {
        if (ReadCarStatus(SEATBELT) == INSERT_SEATBELT) {
            // 再次提示
            AppTimer_add(PrepareTimeout2, D_SEC(10));
            DEBUG("设置再次提醒");
        }
        AppTimer_add(PrepareTimeout, D_MIN(2));
        DEBUG("设置2分钟超时");
    }
    hint_cnt++;
}
static void PrepareTimeout(union sigval sig)
{
    DEBUG("上车准备超时");
    AppTimer_delete(PrepareTimeout);
    exec = false;
    PrepareOver(-2);
}
static void PrepareTimeout2(union sigval sig)
{
    AppTimer_delete(PrepareTimeout2);
    PlayTTS(examParam.prepare_tts, TtsBack);
}
lib/src/main/cpp/test_items2/prepare.h
New file
@@ -0,0 +1,14 @@
//
// Created by YY on 2020/12/16.
//
#ifndef MYAPPLICATION2_PREPARE_H
#define MYAPPLICATION2_PREPARE_H
#include <cstdint>
void StartPrepare(void);
void handlePrepare(uint16_t sensor_id, int value);
void PrepareOver(int res);
#endif //MYAPPLICATION2_PREPARE_H
lib/src/main/cpp/test_items2/road_exam.cpp
@@ -859,17 +859,17 @@
    if (newLineType >= 100) {
        newLineType -= 100;
        DEBUG("非法跨越分道线");
        AddExamFault(11, rtkTime);
        AddExamFault(30119, rtkTime);
    }
    if (newLineType == LINE_SOLID && CrashLineType != LINE_SOLID) {
        // 车辆行驶中骑轧车道中心实线或者车道边缘实线,不合格
        DEBUG("撞道路边缘线");
        AddExamFault(11, rtkTime);
        AddExamFault(30119, rtkTime);
    }
    if (newLineType == LINE_BOUNDARY && CrashLineType != LINE_BOUNDARY) {
        // 车辆越界,逃跑了,不合格
        DEBUG("车辆越界");
        AddExamFault(3, rtkTime);
        AddExamFault(30103, rtkTime);
    }
    if (newLineType == LINE_DOTTED || newLineType == LINE_HALF_SOLID_LEFT || newLineType == LINE_HALF_SOLID_RIGHT) {
@@ -896,7 +896,7 @@
                    DEBUG("长时间压虚线");
                    checkCrashGreenTimeout = 2;
                    // 长时间骑轧车道分界线行驶,不合格
                    AddExamFault(12, rtkTime);
                    AddExamFault(30120, rtkTime);
                }
            }
        } else {
@@ -935,7 +935,7 @@
                if (turnSignalStatus.value != LEFT_TURN_LIGHT) {
                    DEBUG("变调未打灯!!");
                    // 没打灯,不合格
                    AddExamFault(13, rtkTime);
                    AddExamFault(30121, rtkTime);
                } else if (TimeGetDiff(&crashGreenStartTime, &turnSignalStatus.time) <
                           examParam.turn_signal_min_advance) {
                    DEBUG("转向灯时间不足 %02d-%02d-%02d %02d:%02d:%02d.%03d  -> %02d-%02d-%02d %02d:%02d:%02d.%03d",
@@ -946,13 +946,13 @@
                          turnSignalStatus.time.mm, turnSignalStatus.time.ss, turnSignalStatus.time.mss * 10);
                    // 不足3秒,不合格
                    AddExamFault(14, rtkTime);
                    AddExamFault(30122, rtkTime);
                }
            } else {
                if (turnSignalStatus.value != RIGHT_TURN_LIGHT) {
                    DEBUG("变调未打灯!!");
                    // 没打灯,不合格
                    AddExamFault(13, rtkTime);
                    AddExamFault(30121, rtkTime);
                } else if (TimeGetDiff(&crashGreenStartTime, &turnSignalStatus.time) <
                        examParam.turn_signal_min_advance) {
                    DEBUG("转向灯时间不足 %02d-%02d-%02d %02d:%02d:%02d.%03d  -> %02d-%02d-%02d %02d:%02d:%02d.%03d",
@@ -962,13 +962,13 @@
                          turnSignalStatus.time.YY, turnSignalStatus.time.MM, turnSignalStatus.time.DD, turnSignalStatus.time.hh,
                          turnSignalStatus.time.mm, turnSignalStatus.time.ss, turnSignalStatus.time.mss * 10);
                    // 不足3秒,不合格
                    AddExamFault(14, rtkTime);
                    AddExamFault(30122, rtkTime);
                }
            }
            if (((ChangeLane.gain < 0 && gain < 0) || (ChangeLane.gain > 0 && gain > 0)) && TimeGetDiff(rtkTime, &ChangeLane.time) < examParam.continuous_change_lane_min_time) {
                DEBUG("连续变道");
                AddExamFault(15, rtkTime);
                AddExamFault(30125, rtkTime);
            }
            ChangeLane.gain = gain;
            ChangeLane.time = *rtkTime;
@@ -1304,7 +1304,7 @@
                occurOverSpeed = true;
                // 超速,不合格
                DEBUG("超速 %f", ConvertMs2KMh(speed));
                AddExamFault(10, rtkTime);
                AddExamFault(30118, rtkTime);
            }
        } else if (ConvertMs2KMh(speed) < examParam.road_max_speed - 5) {
            occurOverSpeed = false;
@@ -1316,7 +1316,7 @@
            if (!occurSecondBreak) {
                DEBUG("副刹车动作了");
                occurSecondBreak = true;
                AddExamFault(17, rtkTime);
                AddExamFault(30132, rtkTime);
            }
        } else {
            occurSecondBreak = false;
@@ -1329,7 +1329,7 @@
        if (currGear != GEAR_N && prevGear == GEAR_N) {
            // 一次换挡
            if (gearChange == currGear && TimeGetDiff(rtkTime, &gearChangeTimePoint) < D_SEC(5)) {
                AddExamFault(7, rtkTime);
                AddExamFault(30113, rtkTime);
            }
            gearChange = currGear;
@@ -1392,7 +1392,7 @@
                TimeGetDiff(rtkTime, &gearNSlideTimePoint) > examParam.gear_n_allow_time) {
                // 空档滑行超5秒,不合格
                DEBUG("挡位滑行,超过5秒");
                AddExamFault(8, rtkTime);
                AddExamFault(30114, rtkTime);
                GearNSlideStatus = 2;
            }
        } else if (GearNSlideStatus != 0) {
@@ -1409,7 +1409,7 @@
        if (gearErrorTime > examParam.gear_speed_error_cumulative_time) {
            // 累计15秒,挡位-车速不匹配,不合格
            DEBUG("挡位错误超过15秒");
            AddExamFault(6, rtkTime);
            AddExamFault(30112, rtkTime);
            gearErrorTime = 0;
        }
@@ -1429,7 +1429,7 @@
                if (slideNormalDistance) {
                    // 后滑,扣10分
                    AddExamFault(18, rtkTime);
                    AddExamFault(30202, rtkTime);
                    DEBUG("后滑超过10厘米, 但不超过30厘米");
                }
@@ -1447,7 +1447,7 @@
            if (TimeGetDiff(rtkTime, &stopTimepoint) >= CorrectPauseCriteria(examParam.road_pause_criteria) && !StopCarOnRedArea &&
                StopOnRedArea(RoadMap, car)) {
                // 停车超2秒,停在红区,不合格
                AddExamFault(16, rtkTime);
                AddExamFault(30128, rtkTime);
                DEBUG("禁停区停车");
                StopCarOnRedArea = true;
            }
@@ -1462,7 +1462,7 @@
                if (slideDistance > examParam.road_slide_red_distance && !slideLongDistance) {
                    // 后滑超过30厘米, 不合格
                    AddExamFault(5, rtkTime);
                    AddExamFault(30107, rtkTime);
                    DEBUG("后滑超过30厘米");
                    slideLongDistance = true;
                    slideNormalDistance = false;
@@ -1528,6 +1528,7 @@
            }
        }
    }
    ExitTarget(RoadMap, car, CarModelList, rtkTime);
    if (RoadMap.calibrate == 0) {
@@ -1552,7 +1553,7 @@
                if (!GetErrorLaneRpt(currExamMapIndex, stop_line_index)) {
                    DEBUG("不按规定车道标向行驶 %d: %d  期望 = %d guide = %d", currExamMapIndex,
                          stop_line_index, act, Lane.guide);
                    AddExamFault(9, rtkTime);
                    AddExamFault(30117, rtkTime);
                    SetErrorLaneRpt(currExamMapIndex, stop_line_index, true);
                }
            }
@@ -1568,7 +1569,9 @@
        road_end_point_t ep = NearbyRoadEndPoint(currExamMapIndex, RoadMap, car);
        // 提示路口怎么走
        HintCrossing(RoadMap, ep.road_index, ep.stop_line_index, ep.distance);
        if (forward == 1) {
            HintCrossing(RoadMap, ep.road_index, ep.stop_line_index, ep.distance);
        }
        double freeSepDis = SeparateLength(RoadMap, Lane, car);
@@ -1692,7 +1695,8 @@
                freeRunExceptDistance = 60.0;
            } else if (RoadExamStatus == ROAD_EXAM_ITEM_CAR_STOP) {
                // 考试结束
                MA_SendExamStatus(1, 1);
                MA_SendExamStatus(0, 0);
                PlayTTS("考试结束", NULL);
            } else {
                freeRunExceptDistance = 2;//250.0;
            }
@@ -1841,23 +1845,23 @@
                    if (turnSignalStatus.value != LEFT_TURN_LIGHT) {
                        DEBUG("变调未打灯!!");
                        // 没打灯,不合格
                        AddExamFault(13, rtkTime);
                        AddExamFault(30121, rtkTime);
                    } else if (TimeGetDiff(&beginTurnTime, &turnSignalStatus.time) <
                            examParam.turn_signal_min_advance) {
                        DEBUG("转向灯时间不足");
                        // 不足3秒,不合格
                        AddExamFault(14, rtkTime);
                        AddExamFault(30122, rtkTime);
                    }
                } else {
                    if (turnSignalStatus.value != RIGHT_TURN_LIGHT) {
                        DEBUG("变调未打灯!!");
                        // 没打灯,不合格
                        AddExamFault(13, rtkTime);
                        AddExamFault(30121, rtkTime);
                    } else if (TimeGetDiff(&beginTurnTime, &turnSignalStatus.time) <
                            examParam.turn_signal_min_advance) {
                        DEBUG("转向灯时间不足");
                        // 不足3秒,不合格
                        AddExamFault(14, rtkTime);
                        AddExamFault(30122, rtkTime);
                    }
                }
            } else if (turnTimeCnt > D_SEC(10)) {
@@ -1986,6 +1990,8 @@
        }
    }
//    DEBUG("检查触发点 道 %d 路 %d", RoadMap.examScheme[0].triggerLines[0].road, RoadMap.roads[index].id);
    for (int j = 0; j < RoadMap.examScheme[0].triggerLines.size(); ++j) {
        if (RoadMap.examScheme[0].triggerLines[j].road == RoadMap.roads[index].id) {
@@ -2098,7 +2104,7 @@
                TriggerDetect.insert(pair<int, trigger_detect_t>(j, up));
                DEBUG("观察子<%d> 加入 %f", j, MAX(dist1, dist2));
                DEBUG("观察子<%d> road_id %d 加入 (%f,%f)", j, RoadMap.roads[index].id, RoadMap.examScheme[0].triggerLines[j].points[0].X, RoadMap.examScheme[0].triggerLines[j].points[0].Y);
            }
        }
    }
lib/src/main/cpp/test_items2/stop_car.cpp
@@ -43,7 +43,7 @@
    if (roadIndex < 0) {
        DEBUG("停车距离超标,靠边停车结束");
        AddExamFault(33, rtkTime);
        AddExamFault(40602, rtkTime);
        return false;
    }
@@ -69,15 +69,16 @@
                    DistanceOf(p2, car->carXY[ car->right_rear_tire[TIRE_OUTSIDE] ]) > examParam.stop_car_edge_red_distance) {
                DEBUG("停车超出路边0.5米");
                // 停车距离超过50厘米,不合格
                AddExamFault(36, rtkTime);
                AddExamFault(40606, rtkTime);
                return false;
            } else if (DistanceOf(p1, car->carXY[ car->right_front_tire[TIRE_OUTSIDE] ]) > examParam.stop_car_edge_yellow_distance ||
                       DistanceOf(p2, car->carXY[ car->right_rear_tire[TIRE_OUTSIDE] ]) > examParam.stop_car_edge_yellow_distance) {
                DEBUG("停车超出路边0.3米");
                // 停车距离超过30厘米,扣10分
                AddExamFault(37, rtkTime);
                AddExamFault(40607, rtkTime);
            }
            time = *rtkTime;
            setup = 4;
        }
    } else if (setup == 4) {
@@ -89,7 +90,7 @@
        if (!BreakHandbreakReleaseSametime && brk.value == BREAK_INACTIVE && hbrk.value == BREAK_INACTIVE) {
            // 拉手刹前,松脚刹,扣10分
            DEBUG("拉手刹前,松脚刹");
            AddExamFault(39, rtkTime);
            AddExamFault(40609, rtkTime);
            BreakHandbreakReleaseSametime = true;
        }
@@ -98,12 +99,12 @@
                if (rpm.value > ENGINE_MIN_ROTATE) {
                    // 下车前,不熄火,扣5分
                    DEBUG("下车前,不熄火");
                    AddExamFault(40, rtkTime);
                    AddExamFault(40610, rtkTime);
                }
                if (hbrk.value == BREAK_INACTIVE) {
                    // 开门前,未拉手刹, 扣10分
                    DEBUG("开门前,未拉手刹");
                    AddExamFault(38, rtkTime);
                    AddExamFault(40608, rtkTime);
                }
                time = *rtkTime;
                OpenDoor = true;
@@ -112,7 +113,13 @@
            if (TimeGetDiff(rtkTime, &time) > examParam.stop_car_open_door_allow_time) {
                // 开门时间超过15秒,不合格
                DEBUG("开门时间超过15秒");
                AddExamFault(35, rtkTime);
                AddExamFault(40605, rtkTime);
                return false;
            }
        } else {
            if (TimeGetDiff(rtkTime, &time) > D_SEC(30)) {
                DEBUG("完成停车超时");
                PlayTTS(examParam.stop_car_end_tts, NULL);
                return false;
            }
        }
@@ -127,7 +134,7 @@
    if (ReadOdo() - beginOdo > examParam.stop_car_limit_distance) {
        // 150米内未停车,不合格
        DEBUG("停车距离超标,靠边停车结束");
        AddExamFault(33, rtkTime);
        AddExamFault(40602, rtkTime);
        return false;
    }
lib/src/main/cpp/test_items2/through_something.cpp
@@ -150,7 +150,7 @@
                    SetTargetReduceRec(TargetReduceRec2, key, rec | OVER_SPEED);
                    DEBUG("通过学校区域超速 %f kmh", ConvertMs2KMh(speed));
                    AddExamFault(49, rtkTime);
                    AddExamFault(41101, rtkTime);
                }
            } else if (distance1 < -1e-3 && distance2 < -1e-3) {
                if (rec != NOT_ENTER) {
@@ -191,26 +191,26 @@
                        DEBUG("不按规定减速");
                        if (ExamSchemeCrossing(RoadMap, road, x) == ROAD_ACTIVE_FORWARD) {
                            AddExamFault(41, rtkTime);
                            AddExamFault(40701, rtkTime);
                        } else if (ExamSchemeCrossing(RoadMap, road, x) ==
                                   ROAD_ACTIVE_TURN_LEFT) {
                            AddExamFault(43, rtkTime);
                            AddExamFault(40801, rtkTime);
                        } else if (ExamSchemeCrossing(RoadMap, road, x) ==
                                   ROAD_ACTIVE_TURN_RIGHT) {
                            AddExamFault(46, rtkTime);
                            AddExamFault(40901, rtkTime);
                        }
                    }
                    if (!(it->second & STOP_CAR) && RoadMap.roads[road].stopLine[x].stopFlag) {
                        // 不停车瞭望,不合格
                        DEBUG("不停车瞭望");
                        if (ExamSchemeCrossing(RoadMap, road, x) == ROAD_ACTIVE_FORWARD) {
                            AddExamFault(42, rtkTime);
                            AddExamFault(40701, rtkTime);
                        } else if (ExamSchemeCrossing(RoadMap, road, x) ==
                                   ROAD_ACTIVE_TURN_LEFT) {
                            AddExamFault(44, rtkTime);
                            AddExamFault(40801, rtkTime);
                        } else if (ExamSchemeCrossing(RoadMap, road, x) ==
                                   ROAD_ACTIVE_TURN_RIGHT) {
                            AddExamFault(47, rtkTime);
                            AddExamFault(40901, rtkTime);
                        }
                    }
                }
@@ -245,12 +245,12 @@
            if (RoadMap.specialAreas[x].type == ZEBRA_CROSSING &&
                !(it->second & REDUCE_SPEED)) {
                DEBUG("人行道 不按规定减速");
                AddExamFault(48, rtkTime);
                AddExamFault(41001, rtkTime);
            }
            if (RoadMap.specialAreas[x].type == BUS_STATION_AREA &&
                !(it->second & REDUCE_SPEED)) {
                DEBUG("公交站 不按规定减速");
                AddExamFault(50, rtkTime);
                AddExamFault(41201, rtkTime);
            }
            RemoveTargetReduceRec(TargetReduceRec2, it->first);
            goto RECHECK2;
lib/src/main/java/com/anyun/exam/lib/InstallUtil.java
@@ -1,9 +1,14 @@
package com.anyun.exam.lib;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.util.Log;
import java.io.ByteArrayOutputStream;
@@ -14,6 +19,10 @@
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;
public class InstallUtil {
    public static final String TAG = InstallUtil.class.getCanonicalName();
@@ -144,23 +153,59 @@
            try {
                Log.d(TAG, "升级app 文件存在 当前ver " + getVerCode() + " 当前Name " + getVerName() + " 目标ver " + getVersionCodeFromApk(context, file.getAbsolutePath()) + " 目标name " + getVersionNameFromApk(context, file.getAbsolutePath()));
//                Signature[] sig = getSignature();
//                Signature[] sig2 = getSignature(file.getAbsolutePath());
                Signature[] sig = getSignature();
                Signature[] sig2 = getSignature(file.getAbsolutePath());
                /*if ( getFingerprint(sig[0], "SHA-1").equals(getFingerprint(sig2[0], "SHA-1")))*/ {
                    if ( getVerCode() <= getVersionCodeFromApk(context, file.getAbsolutePath()) ) {
                if ( getFingerprint(sig[0], "SHA-1").equals(getFingerprint(sig2[0], "SHA-1"))) {
                    if ( getVerCode() < getVersionCodeFromApk(context, file.getAbsolutePath()) ||
                            (getVerCode() == getVersionCodeFromApk(context, file.getAbsolutePath()) &&
                                    !getVerName().equals(getVersionNameFromApk(context, file.getAbsolutePath())))) {
                        Log.d(TAG, "安装文件  " + file.getAbsolutePath());
                        String result = execCommand("pm", "install", "-i", getPackageName(), "--user", "0", "-r", "-d", file.getAbsolutePath());
                        Log.d(TAG, "安装结果  " + result);
                    } else {
                        file.delete();
                    }
                } /*else {
                } else {
                    file.delete();
                }*/
                }
            } catch (Exception e) {
                Log.e(TAG, "安装发生错误 " + e.getMessage());
            }
        }
    }
    public void InstallAppNormal(Context context, String path) {
        File file = new File(path);
        Log.d(TAG, "ManualInstall " + path);
        if (file.exists() && file.isFile()) {
            Signature[] sig = getSignature();
            Signature[] sig2 = getSignature(file.getAbsolutePath());
            if (getFingerprint(sig[0], "SHA-1").equals(getFingerprint(sig2[0], "SHA-1")) &&
                    (getVerCode() < getVersionCodeFromApk(context, file.getAbsolutePath()) ||
                    (getVerCode() == getVersionCodeFromApk(context, file.getAbsolutePath()) &&
                            !getVerName().equals(getVersionNameFromApk(context, file.getAbsolutePath()))))) {
                Intent intent = new Intent(Intent.ACTION_VIEW);
                Uri data;
                String type = "application/vnd.android.package-archive";
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
                    data = Uri.fromFile(file);
                } else {
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    String authority = context.getPackageName() + ".fileProvider";
                    data = FileProvider.getUriForFile(context, authority, file);
                }
                intent.setDataAndType(data, type);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(intent);
            } else {
                Log.d(TAG, "File illegal");
            }
        } else {
            Log.d(TAG, "File not exist");
        }
    }
@@ -223,4 +268,37 @@
        }
        return result;
    }
/*
    private void checkIsAndroidO() {
        if (Build.VERSION.SDK_INT >= 26) {
            if (context.getPackageManager().canRequestPackageInstalls()) {
                mMainPresenter.installApk();
            } else {
                //请求安装未知应用来源的权限
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES},INSTALL_PACKAGES_REQUEST_CODE);
            }
        } else {
            mMainPresenter.installApk();
        }
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case INSTALL_PACKAGES_REQUEST_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    mMainPresenter.installApk();
                } else {
                    //  引导用户手动开启安装权限
                    Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
                    startActivityForResult(intent, GET_UNKNOWN_APP_SOURCES);
                }
                break;
            default:
                break;
        }
    }*/
}
lib/src/main/java/com/anyun/exam/lib/RemoteService.java
@@ -13,6 +13,7 @@
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
@@ -36,6 +37,7 @@
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
@@ -55,6 +57,9 @@
 */
public class RemoteService extends Service {
    private static final String TAG = "RemoteService";
    public static final boolean mAyDevice = true;
    /**服务是否销毁标志*/
    private AtomicBoolean mIsServiceDestroyed = new AtomicBoolean(false);
    private RemoteCallbackList<IListenerInterface> mListenerList = new RemoteCallbackList();
@@ -134,14 +139,31 @@
//        PlayRing(this, ringUri);
        LimitMaxMinVolume();
        if (mAyDevice == false) {
            mBluetooth = Bluetooth.getInstance(getApplicationContext(), mHandler);
            mBluetooth.OpenBluetooth();
            // Initialize the BluetoothChatService to perform mBluetooth connections
            mChatService = new BluetoothChatService(this, mHandler);
        }
        Log.d(TAG, "基带版本 " + getBaseband_Ver());
        String ver = getBaseband_Ver();
        mBluetooth = Bluetooth.getInstance(getApplicationContext(), mHandler);
        mBluetooth.OpenBluetooth();
        // Initialize the BluetoothChatService to perform mBluetooth connections
        mChatService = new BluetoothChatService(this, mHandler);
        new Thread(new TestCls()).start();
    }
    class TestCls implements Runnable {
        @Override
        public void run() {
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
            }
            upgrade.ManualUpgrade(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "/Download/aks3b.apk");
        }
    }
    class AutoUpdateMcuThread implements Runnable {
@@ -273,7 +295,7 @@
    class StartNative implements Runnable {
        @Override
        public void run() {
            startNative();
            startNative(mAyDevice);
        }
    }
@@ -296,10 +318,10 @@
        Process.killProcess(Process.myPid());
    }
    private void onMessageArrived(int cmd, String json) {
    private int onMessageArrived(int cmd, String json) {
        Log.d(TAG, "SendMsgToMainProc cmd = " + String.format("%04X", cmd) + " json = " + json);
        int N = mListenerList.getRegisteredCallbackCount();
        int ret = -1;
        synchronized(this) {
            mListenerList.beginBroadcast();
@@ -308,19 +330,24 @@
                if (mListener != null) {
                    try {
                        mListener.onMessageArrived(cmd, json);
                        ret = 0;
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }else{
                }
            }
            mListenerList.finishBroadcast();
        }
        return ret;
    }
    public void SendMsgToMainProc(int cmd, String value) {
    public int SendMsgToMainProc(int cmd, String value) {
        if (!mIsServiceDestroyed.get()){
            onMessageArrived(cmd, value);
            return onMessageArrived(cmd, value);
        }
        return -2;
    }
    public String javaDESEncrypt(String plaintext, String key) {
@@ -539,7 +566,7 @@
        System.loadLibrary("native-lib");
    }
    public native void startNative();
    public native void startNative(boolean ayDevice);
    public native void MainProcMsgEntry(int cmd, String value);
    public native void MainProcBinMsgEntry(int cmd, byte []data, int length);
    public native void UpgradeMcu(String vercode, byte []rom);
lib/src/main/java/com/anyun/exam/lib/Upgrade.java
@@ -39,6 +39,7 @@
            synchronized (Upgrade.class) {
                if (instance == null) {
                    instance = new Upgrade(context);
                    instance.context = context;
                }
            }
        }
@@ -249,6 +250,10 @@
        handlerCheckNewVersion.postDelayed(runnableCheckNewVersion, 100);
    }
    public void ManualUpgrade(String path) {
        installUtil.InstallAppNormal(context, path);
    }
    class DMCB implements DownloadManagerCallback {
        @Override
        public void DownloadComplete(String title, String path) {
@@ -258,7 +263,11 @@
                    Signature[] sig2 = installUtil.getSignature(path);
                    if (sig != null && sig2 != null && installUtil.getFingerprint(sig[0], "SHA-1").equals(installUtil.getFingerprint(sig2[0], "SHA-1"))) {
                        installUtil.InstallApp(path);
                        if (RemoteService.mAyDevice) {
                            installUtil.InstallApp(path);
                        } else {
                            installUtil.InstallAppNormal(context, path);
                        }
                    }
                }
            }