yy1717
2021-01-19 87156fa3adfa2e3232a6f6e612584aa8a4ebaea1
添加模拟灯光
11个文件已修改
776 ■■■■■ 已修改文件
lib/src/main/cpp/common/net.cpp 354 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/common/net.h 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/driver_test.cpp 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/master/comm_if.cpp 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/mcu/mcu_if.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/rtk_module/virtual_rtk.cpp 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/rtk_module/virtual_rtk.h 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/rtk_platform/parse_net.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/rtk_platform/platform.cpp 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_common/car_sensor.cpp 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/test_items2/dummy_light.cpp 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
lib/src/main/cpp/common/net.cpp
@@ -13,19 +13,77 @@
#include <arpa/inet.h>
#include <regex>
#include <pthread.h>
#include <semaphore.h>
#include <string>
#include "net.h"
#include "../jni_log.h"
#define DEBUG(fmt, args...)     LOGD("<net> <%s>: " fmt, __func__, ##args)
#define PARSE_BUFF_SIZE     4096
using namespace std;
CTcpPort::CTcpPort()
{
    m_iServiceType = TYPE_CLIENT;
    m_sIp.clear();
    m_nPort = 0;
    m_connected = false;
    m_pClientSocket = 0;
    m_pServerSocket = 0;
    event_func = NULL;
    event_func_context = NULL;
    receive_data_func = NULL;
    receive_data_func_context = NULL;
}
CTcpPort::~CTcpPort()
{
    CloseTcpPort();
}
bool CTcpPort::IsOpen(void)
{
    if (m_iServiceType == TYPE_SERVER) {
        if (m_pServerSocket > 0) {
            return true;
        } else {
            return false;
        }
    } else {
        if (m_pClientSocket > 0) {
            return true;
        } else {
            return false;
        }
    }
}
bool CTcpPort::OpenTcpPort(const char *ip, int port)
{
    if (IsOpen()) {
        return true;
    }
    m_sIp = ip;
    m_nPort = port;
    pthread_t platform_pid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached
    pthread_create(&platform_pid, &attr, TcpConnectThread, this);
    return true;
}
/*************************************************************
    host_name:domain name
    net_addr:return numbers-and-dots notation
*/
int GetHostIP(const char *host_name, char *net_addr)
int CTcpPort::GetHostIP(const char *host_name, char *net_addr)
{
    struct hostent *hptr;
    char **pptr;
@@ -68,7 +126,7 @@
    return -2;
}
static bool is_domain_name(const char *ip)
bool CTcpPort::is_domain_name(const char *ip)
{
    regex pattern0("^((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})(\\.((2(5[0-5]|[0-4]\\d))|[0-1]?\\d{1,2})){3}$");
    string target(ip);
@@ -76,7 +134,7 @@
    return !regex_match(target, pattern0);
}
static int socket_set_keepalive(int fd)
int CTcpPort::socket_set_keepalive(int fd)
{
    int alive, idle, cnt, intv;
@@ -133,7 +191,7 @@
    return 0;
}
static int tcp_connect(char *ip, uint16_t port)
int CTcpPort::tcp_connect(char *ip, uint16_t port)
{
    struct sockaddr_in server_sockaddr;
    int soc;
@@ -259,51 +317,116 @@
    return( -1 );
}
static int udp_connect(const char *ip, uint16_t port) {
    struct sockaddr_in server_sockaddr;
    int soc;
    int opt;
    int arg;
void *CTcpPort::TcpConnectThread(void *p)
{
    CTcpPort *pCTcpPort = (CTcpPort *)p;
    if ((soc = socket(PF_INET, SOCK_DGRAM, 0)) == -1) {
        return -1;
    char net_addr[32] = {0};
    if (pCTcpPort->is_domain_name(pCTcpPort->m_sIp.c_str())) {
        if (pCTcpPort->GetHostIP(pCTcpPort->m_sIp.c_str(), net_addr) != 0) {
            goto CONNECT_END;
        }
    } else {
        strcpy(net_addr, pCTcpPort->m_sIp.c_str());
    }
    /*Enable send broadcast packet*/
    opt = 1;
    if (setsockopt(soc, SOL_SOCKET, SO_BROADCAST, &opt, sizeof(opt)) != 0) {
        perror("setsockopt");
        close(soc);
        return -1;
    pCTcpPort->m_pClientSocket = pCTcpPort->tcp_connect(net_addr, pCTcpPort->m_nPort);
    if (pCTcpPort->m_pClientSocket > 0) {
        if (pCTcpPort->event_func != NULL) {
            pCTcpPort->event_func(0, pCTcpPort, pCTcpPort->event_func_context);
        }
        pthread_t platform_pid;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached
        pthread_create(&platform_pid, &attr, TcpListenThread, p);
    } else {
        if (pCTcpPort->event_func != NULL) {
            pCTcpPort->event_func(-1, pCTcpPort, pCTcpPort->event_func_context);
        }
    }
    // Set non-blocking
    if( (arg = fcntl(soc, F_GETFL, NULL)) < 0 ) {
        close(soc);
        return -1;
    }
    if ( fcntl(soc, F_SETFL, arg | O_NONBLOCK) < 0 ) {
        close(soc);
        return -1;
    }
    server_sockaddr.sin_family = AF_INET;
    server_sockaddr.sin_addr.s_addr = inet_addr(ip);//htonl(INADDR_ANY);
    server_sockaddr.sin_port = htons(port);
    bzero(&server_sockaddr.sin_zero, 8);
    return soc;
CONNECT_END:
    pthread_exit(NULL);
}
int WriteTCP(int fd, const uint8_t * buf, uint32_t len)
void *CTcpPort::TcpListenThread(void *p)
{
    int fds_ret;
    struct timeval tv;
    fd_set rdfds;
    fd_set exfds;
    uint8_t RxBuf[PARSE_BUFF_SIZE];
    CTcpPort *pCTcpPort = (CTcpPort *)p;
    while (pCTcpPort->m_pClientSocket > 0) {
        tv.tv_sec = 5;
        tv.tv_usec = 0;
        FD_ZERO(&rdfds); //clean
        FD_SET(pCTcpPort->m_pClientSocket, &rdfds); //set
        fds_ret = select(pCTcpPort->m_pClientSocket + 1, &rdfds, NULL, NULL, &tv);
        if (fds_ret < 0) {
            break;
        } else if(fds_ret == 0) {
            //Occur failure(such as line disconnect)
        } else if(FD_ISSET(pCTcpPort->m_pClientSocket, &rdfds)) {
            int recvLen = recv(pCTcpPort->m_pClientSocket, RxBuf, sizeof(RxBuf), 0);
            if (recvLen == 0) {
                LOGW("tcp error TCP disconnected 0 errno = %d", errno);
                break;
            } else if (recvLen < 0) {
                if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
                } else {
                    LOGW("tcp error TCP disconnected errno = %d", errno);;
                    break;
                }
            }
            if (recvLen > 0) {
                if (pCTcpPort->receive_data_func != NULL) {
                    pCTcpPort->receive_data_func(RxBuf, recvLen, pCTcpPort, pCTcpPort->receive_data_func_context);
                }
            }
        }
    }
    pCTcpPort->CloseTcpPort();
    if (pCTcpPort->event_func) {
        pCTcpPort->event_func(-1, pCTcpPort, pCTcpPort->event_func_context);
    }
    pthread_exit(NULL);
}
void CTcpPort::set_event_callback(void (*callback)(int, void *, void *), void *context)
{
    event_func = callback;
    event_func_context = context;
}
void CTcpPort::set_data_callback(void (*callback)(void *, int, void *, void *), void *context)
{
    receive_data_func = callback;
    receive_data_func_context = context;
}
int CTcpPort::WriteTCP(const uint8_t * buf, uint32_t len)
{
    int ret = 0;
    int fds_ret;
    struct timeval tv;
    fd_set rdfds;
    if (fd < 0)
    if (m_pClientSocket <= 0)
        return -2;
    /*******************************************************
@@ -314,9 +437,9 @@
    tv.tv_usec = 0;
    FD_ZERO(&rdfds); //clean
    FD_SET(fd, &rdfds); //set
    FD_SET(m_pClientSocket, &rdfds); //set
    fds_ret = select(fd + 1, NULL, &rdfds, NULL, &tv);
    fds_ret = select(m_pClientSocket + 1, NULL, &rdfds, NULL, &tv);
    if (fds_ret < 0) {
        DEBUG("tcp error send select error");
@@ -325,8 +448,8 @@
        DEBUG("tcp error Occur failure(such as line disconnect)");
        //Occur failure(such as line disconnect)
        ret = -1;
    } else if(FD_ISSET(fd, &rdfds)) {
        ret = send(fd, buf, len, 0);
    } else if(FD_ISSET(m_pClientSocket, &rdfds)) {
        ret = send(m_pClientSocket, buf, len, 0);
        if(ret == -1) {
            DEBUG("tcp error TCP Send Error");
        }
@@ -337,148 +460,15 @@
    return ret;
}
int ReadTCP(int fd, uint8_t * buf, uint32_t len)
bool CTcpPort::CloseTcpPort(void)
{
    if (fd < 0) {
        return -2;
    DEBUG("DisconnectTCP fd = %d", m_pClientSocket);
    if (m_pClientSocket > 0) {
        shutdown(m_pClientSocket, SHUT_RDWR);
        close(m_pClientSocket);
        m_pClientSocket = 0;
        return true;
    }
    int recvLen = recv(fd, buf, len, 0);        //read socket data from server
    if (recvLen == 0) {
        LOGW("tcp error TCP disconnected 0 errno = %d", errno);
        return -1;
    } else if (recvLen < 0) {
        if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
            return 0;
        } else {
            LOGW("tcp error TCP disconnected errno = %d", errno);;
            return -1;
        }
    }
    return recvLen;
}
int ConnectTCP(const char *ip, uint16_t port)
{
    char net_addr[32] = {0};
    if (is_domain_name(ip)) {
        if (GetHostIP(ip, net_addr) != 0) {
            return -3;
        }
    } else {
        strcpy(net_addr, ip);
    }
    return tcp_connect(net_addr, port);
}
void DisconnectTCP(int fd)
{
    DEBUG("DisconnectTCP fd = %d", fd);
    if (fd >= 0) {
        shutdown(fd, SHUT_RDWR);
        close(fd);
    }
}
int EstablishUDP(const char *ip, uint16_t port)
{
    char net_addr[32] = {0};
    if (is_domain_name(ip)) {
        if (GetHostIP(ip, net_addr) != 0) {
            return -3;
        }
    } else {
        strcpy(net_addr, ip);
    }
    return udp_connect(net_addr, port);
}
void RemoveUDP(int fd)
{
    close(fd);
}
int WriteUDP(int fd, char *ip, uint16_t port, const uint8_t * buf, uint32_t len)
{
    int ret = 0;
    int fds_ret;
    struct timeval tv;
    fd_set rdfds;
    if (fd < 0)
        return -2;
    /*******************************************************
    TCP send with nonblock, if occur failure(such as line disconnect...),
    will send timeout, so terminate TCP.
    */
    tv.tv_sec = 5;
    tv.tv_usec = 0;
    FD_ZERO(&rdfds); //clean
    FD_SET(fd, &rdfds); //set
    fds_ret = select(fd + 1, NULL, &rdfds, NULL, &tv);
    if (fds_ret < 0)
    {
        DEBUG("UDP send select error");
        return -1;
    }
    else if(fds_ret == 0)
    {
        DEBUG("Occur failure(such as line disconnect)");
        ret = -1;
    }
    else if(FD_ISSET(fd, &rdfds))
    {
        struct sockaddr_in server_sockaddr;
        server_sockaddr.sin_family = AF_INET;
        server_sockaddr.sin_addr.s_addr = inet_addr(ip);//htonl(INADDR_ANY);
        server_sockaddr.sin_port = htons(port);
        bzero(&server_sockaddr.sin_zero, 8);
        ret = sendto(fd, buf, len, 0, (struct sockaddr *)&server_sockaddr, sizeof(struct sockaddr_in));
        if(ret == -1)
        {
            DEBUG("UDP Send Error");
        }
    }
    else
    {
        DEBUG("UDP send has error\n");
    }
    return ret;
}
int ReadUDP(int fd, uint8_t * buf, uint32_t len)
{
    struct sockaddr_in from_addr;
    socklen_t from_len;
    int recvLen = recvfrom(fd, buf, len, 0,
                           (struct sockaddr *) &from_addr,
                           &from_len);//read socket data from server//
    if (recvLen == 0) {
        return 0;
    } else if (recvLen < 0) {
        if (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) {
            return 0;
        } else {
            DEBUG("UDP ERROR!! = %d", errno);
            return -1;
        }
    }
    return recvLen;
    return false;
}
lib/src/main/cpp/common/net.h
@@ -5,13 +5,53 @@
#ifndef RTKBASESTATION_NET_H
#define RTKBASESTATION_NET_H
int WriteTCP(int fd, const uint8_t * buf, uint32_t len);
int ReadTCP(int fd, uint8_t * buf, uint32_t len);
int ConnectTCP(const char *ip, uint16_t port);
void DisconnectTCP(int fd);
int EstablishUDP(const char *ip, uint16_t port);
void RemoveUDP(int fd);
int WriteUDP(int fd, char *ip, uint16_t port, const uint8_t * buf, uint32_t len);
int ReadUDP(int fd, uint8_t * buf, uint32_t len);
#include <string>
enum SERVICE_TYPE {
    TYPE_SERVER,
    TYPE_CLIENT
};
class CTcpPort
{
public:
    SERVICE_TYPE m_iServiceType;
    std::string m_sIp;
    int m_nPort;
    bool m_connected;
    int m_pServerSocket;
    int m_pClientSocket;
public:
    CTcpPort();
    virtual ~CTcpPort();
    bool IsOpen(void);
    bool CloseTcpPort();
    bool OpenTcpPort(const char *ip, int port);
    void set_event_callback(void (*callback)(int, void *, void *), void *context);
    void set_data_callback(void (*callback)(void *, int, void *, void *), void *context);
    int WriteTCP(const uint8_t * buf, uint32_t len);
private:
    int GetHostIP(const char *host_name, char *net_addr);
    bool is_domain_name(const char *ip);
    int socket_set_keepalive(int fd);
    int tcp_connect(char *ip, uint16_t port);
    void(*event_func)(int, void *, void *);    //数据回调函数指针
    void *event_func_context;    //数据回调函数上下文
    void(*receive_data_func)(void *, int, void *, void *);    //数据回调函数指针
    void *receive_data_func_context;    //数据回调函数上下文
    static void *TcpConnectThread(void *p);
    static void *TcpListenThread(void *p);
};
//int WriteTCP(int fd, const uint8_t * buf, uint32_t len);
//int ReadTCP(int fd, uint8_t * buf, uint32_t len);
//int ConnectTCP(const char *ip, uint16_t port);
//void DisconnectTCP(int fd);
#endif //RTKBASESTATION_NET_H
lib/src/main/cpp/driver_test.cpp
@@ -520,7 +520,15 @@
{
    DEBUG("获取模拟路考灯光测试项目 N = %d %d", n, ExamStart);
    static const int cov[] = {0,
    static const int CONV_TABLE[] = {(FLASH_BEAM_LAMP<<8)+OFF_LIGHT,
                              (TURN_SIGNAL_LAMP<<8)+OFF_LIGHT,
                              (TURN_SIGNAL_LAMP<<8)+OFF_LIGHT,
                              (TURN_SIGNAL_LAMP<<8)+OFF_LIGHT,
                              (FOG_LAMP<<8)+OFF_LIGHT,
                              (CLEARANCE_LAMP<<8)+OFF_LIGHT,
                              (MAIN_BEAM_LAMP<<8)+OFF_LIGHT,
                              (DIPPED_BEAM_LAMP<<8)+OFF_LIGHT,
                              0,
                              (DIPPED_BEAM_LAMP<<8)+DIPPED_BEAM_LIGHT,
                              (MAIN_BEAM_LAMP<<8)+MAIN_BEAM_LIGHT,
                              (CLEARANCE_LAMP<<8)+CLEARANCE_LIGHT,
@@ -529,6 +537,8 @@
                              (TURN_SIGNAL_LAMP<<8)+RIGHT_TURN_LIGHT,
                              (TURN_SIGNAL_LAMP<<8)+HAZARD_LIGHTS,
                              (FLASH_BEAM_LAMP<<8)+FLASH_BEAM_LIGHT};
    const int *cov = CONV_TABLE + 8;
    if (ExamStart) return;
@@ -547,10 +557,10 @@
        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]];
            DummyLightContent[i].process.push_back(cov[cfg[i].process[j]]);
        }
        for (int j = 0; j < cfg[i].solution.size(); ++j) {
            DummyLightContent[i].solution[j] = cov[cfg[i].solution[j]];
            DummyLightContent[i].solution.push_back(cov[cfg[i].solution[j]]);
        }
    }
}
@@ -746,7 +756,7 @@
                                     "近光灯",
                                     "雾灯",
                                     "示廓灯",
                                     "远近光",
                                     "闪灯提示",
                                     "远光灯",
                                     "安全带",
                                     "启动引擎",
lib/src/main/cpp/master/comm_if.cpp
@@ -1969,6 +1969,7 @@
            Document doc;
            doc.Parse(value);
            if (!doc.HasParseError()) {
                DEBUG("解析灯光配置...");
                if (doc.HasMember("exam")) {
                    const Value& s = doc["exam"];
                    s.GetInt();
@@ -1979,30 +1980,39 @@
                        int n = 0;
                        struct dummy_light_exam *content = new struct dummy_light_exam[s.Size()];
                        DEBUG("题目数量 %d", s.Size());
                        for(Value::ConstValueIterator itr = s.Begin(); itr != s.End(); ++itr) {
                            if (itr->HasMember("item") && itr->HasMember("tts")) {
                                const Value &s1 = (*itr)["item"];
                                const Value &s2 = (*itr)["tts"];
                                content[n].item = s1.GetInt();
                                content[n].tts = s2.GetString();
                                DEBUG("题目 %s", s2.GetString());
                            }
                            if (itr->HasMember("wrong_code")) {
                                const Value &s = (*itr)["wrong_code"];
                                content[n].wrongCode = s.GetInt();
                                DEBUG("题目wrongCode %d", s.GetInt());
                            }
                            if (itr->HasMember("process")) {
                                const Value& s = doc["process"];
                                const Value& s = (*itr)["process"];
                                for(Value::ConstValueIterator itr2 = s.Begin(); itr2 != s.End(); ++itr2) {
                                    DEBUG("题目process %d", itr2->GetInt());
                                    content[n].process.push_back(itr2->GetInt());
                                }
                            }
                            if (itr->HasMember("solution")) {
                                const Value& s = doc["solution"];
                                const Value& s = (*itr)["solution"];
                                for(Value::ConstValueIterator itr2 = s.Begin(); itr2 != s.End(); ++itr2) {
                                    DEBUG("题目solution %d", itr2->GetInt());
                                    content[n].solution.push_back(itr2->GetInt());
                                }
                            }
lib/src/main/cpp/mcu/mcu_if.cpp
@@ -148,7 +148,11 @@
        if (RxBufLen > 0) {
//            DEBUG("RECV LEN %d", RxBufLen);
            ParseMcu(RxBuf, RxBufLen);
            if (Virtual2IsConnected()) {
            } else {
                ParseMcu(RxBuf, RxBufLen);
            }
            RxBufLen = 0;
        }
    }
lib/src/main/cpp/rtk_module/virtual_rtk.cpp
@@ -12,6 +12,7 @@
#include "../common/apptimer.h"
#include "../defs.h"
#include "parse_gps.h"
#include "../mcu/mcu_if.h"
#define DEBUG(fmt, args...)     LOGD("<virtual_device> <%s>: " fmt, __func__, ##args)
@@ -22,12 +23,18 @@
    int port;
} VAddr;
static CTcpPort *ctp = NULL, *ctp2 = NULL;
static bool virtRtkIsValid = false;
static int connectCnt = 0;
static void TcpEventCallback(int stat, void *p, void *context);
static void TcpDataCallback(void *buffer, int length, void *p, void *context);
static bool virtRtkIsValid2 = false;
static int connectCnt2 = 0;
static void TcpEventCallback2(int stat, void *p, void *context);
static void TcpDataCallback2(void *buffer, int length, void *p, void *context);
static void ConnectLater(union sigval sig);
static void ConnectV(void);
static void *VDataListenThread(void *p);
void InitVirtualDevice(const char *domain_name, int port)
{
@@ -36,7 +43,23 @@
    strcpy(VAddr.domain_name, domain_name);
    VAddr.port = port;
    ConnectV();
    if (ctp == NULL) {
        ctp = new CTcpPort();
        ctp->set_event_callback(TcpEventCallback, NULL);
        ctp->set_data_callback(TcpDataCallback, NULL);
        ctp->OpenTcpPort(domain_name, port);
    }
    if (ctp2 == NULL) {
        ctp2 = new CTcpPort();
        ctp2->set_event_callback(TcpEventCallback2, NULL);
        ctp2->set_data_callback(TcpDataCallback2, NULL);
        ctp2->OpenTcpPort(domain_name, port + 1);
    }
}
bool VirtualIsConnected(void)
@@ -50,21 +73,111 @@
    return temp;
}
bool Virtual2IsConnected(void)
{
    bool temp;
    do {
        temp = virtRtkIsValid2;
    } while (temp != virtRtkIsValid2);
    return temp;
}
static void ConnectLater(union sigval sig) {
    AppTimer_delete(ConnectLater);
    ConnectV();
    if (sig.sival_int == 1) {
        if (ctp != NULL) {
            ctp->OpenTcpPort(VAddr.domain_name, VAddr.port);
        }
    } else {
        if (ctp2 != NULL) {
            ctp2->OpenTcpPort(VAddr.domain_name, VAddr.port + 1);
        }
    }
}
static void ConnectV(void)
static void TcpEventCallback(int stat, void *p, void *context)
{
    pthread_t pid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached
    pthread_create(&pid, &attr, VDataListenThread, &VAddr);
    CTcpPort *pTcpPort = (CTcpPort *)p;
    if (stat == 0) {
        DEBUG("虚拟平台连接成功 %s: %d", pTcpPort->m_sIp.c_str(), pTcpPort->m_nPort);
        virtRtkIsValid = true;
        connectCnt = 0;
        PlayTTS("模拟器连接", NULL);
    } else {
        DEBUG("虚拟平台连接失败");
        virtRtkIsValid = false;
        connectCnt++;
        if (connectCnt < 3) {
            AppTimer_add(ConnectLater, D_SEC(3), 1);
        }
        PlayTTS("模拟器断开", NULL);
    }
}
static void TcpDataCallback(void *buffer, int length, void *p, void *context)
{
    static uint8_t RxBuf[PARSE_BUFF_SIZE];
    static int RxBufLen = 0;
    if (length > 0) {
        memcpy(RxBuf + RxBufLen, buffer, length);
        RxBufLen += length;
        const uint8_t *ptr = parseGPS(RxBuf, RxBuf + RxBufLen);
        if(ptr != RxBuf) {
            memcpy(RxBuf, ptr, RxBufLen - (ptr - RxBuf));
            RxBufLen -= ptr - RxBuf;
        } else if(RxBufLen == PARSE_BUFF_SIZE) {        //填满了,且没有一个\r,都抛弃
            DEBUG("Parse GPS error");
            RxBufLen = 0;
        }
    }
}
static void TcpEventCallback2(int stat, void *p, void *context)
{
    CTcpPort *pTcpPort = (CTcpPort *)p;
    if (stat == 0) {
        DEBUG("灯光虚拟平台连接成功 %s: %d", pTcpPort->m_sIp.c_str(), pTcpPort->m_nPort);
        virtRtkIsValid2 = true;
        connectCnt2 = 0;
        PlayTTS("灯光模拟器连接", NULL);
    } else {
        DEBUG("灯光虚拟平台连接失败");
        virtRtkIsValid2 = false;
        connectCnt2++;
        if (connectCnt2 < 3) {
            AppTimer_add(ConnectLater, D_SEC(3), 2);
        }
        PlayTTS("灯光模拟器断开", NULL);
    }
}
static void TcpDataCallback2(void *buffer, int length, void *p, void *context)
{
    static uint8_t RxBuf[PARSE_BUFF_SIZE];
    static int RxBufLen = 0;
    if (length > 0) {
        memcpy(RxBuf + RxBufLen, buffer, length);
        RxBufLen += length;
        if (RxBufLen > 0) {
            ParseMcu(RxBuf, RxBufLen);
            RxBufLen = 0;
        }
    }
}
/*
static void *VDataListenThread(void *p) {
    struct vSocket *vs = (struct vSocket *)p;
@@ -139,3 +252,4 @@
    pthread_exit(NULL);
}
*/
lib/src/main/cpp/rtk_module/virtual_rtk.h
@@ -7,5 +7,6 @@
void InitVirtualDevice(const char *domain_name, int port);
bool VirtualIsConnected(void);
bool Virtual2IsConnected(void);
#endif //MYAPPLICATION2_VIRTUAL_RTK_H
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 xENABLE_DEBUG_PROTOCOL
using namespace std;
lib/src/main/cpp/rtk_platform/platform.cpp
@@ -25,6 +25,7 @@
#include "../test_items2/stop_car.h"
#include "../test_items2/operate_gear.h"
#include "../test_items2/drive_straight.h"
#include "../rtk_module/virtual_rtk.h"
#define PARSE_BUFF_SIZE         4096
@@ -79,13 +80,12 @@
static bool mAyDevice = false;
struct platformSocket exceptSocket, currSocket;
struct platformSocket exceptSocket;
static sem_t sem_status_changed;
static bool requestPlatformSendRtk = false;
static int platform_tcp_fd = 0;
static CTcpPort *ctp = NULL;
static pthread_mutex_t platform_tx_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t events_mutex = PTHREAD_MUTEX_INITIALIZER;
static struct gpsBrief gbf;
@@ -101,10 +101,12 @@
static void ReqRtkPlatformConfigTimeout(union sigval sig);
static void TcpEventCallback(int stat, void *p, void *context);
static void TcpDataCallback(void *buffer, int length, void *p, void *context);
static void ConnectPlatform(const char *domain_name, int port);
static void ConnectPlatformLater(union sigval sig);
static void *PlatformDataListenThread(void *p);
static void *StatusListenThread(void *p);
static void PlatformChangeEntry(uint32_t events, const uint8_t *data, int length);
@@ -194,14 +196,10 @@
    memset(&rbf, 0, sizeof(rbf));
    memset(&defaultMcuRom, 0, sizeof(defaultMcuRom));
    pthread_mutex_init(&platform_tx_mutex, NULL);
    pthread_mutex_init(&events_mutex, NULL);
    eventQueue = NULL;
    platform_tcp_fd = -1;
    memset(&currSocket, 0, sizeof(currSocket));
    memset(&platformStatus, 0, sizeof(platformStatus));
    sem_init(&sem_status_changed, 0, 0);
@@ -247,14 +245,16 @@
        platformStatus.registed = 0;
    }
    pthread_mutex_lock(&platform_tx_mutex);
    if (platform_tcp_fd > 0 && (exceptSocket.port != currSocket.port || strcmp(currSocket.domain_name, exceptSocket.domain_name))) {
        DisconnectTCP(platform_tcp_fd);
        platform_tcp_fd = -1;
    } else if (platform_tcp_fd <= 0) {
        ConnectPlatform(exceptSocket.domain_name, exceptSocket.port);
    }
    pthread_mutex_unlock(&platform_tx_mutex);
    ConnectPlatform(exceptSocket.domain_name, exceptSocket.port);
//    pthread_mutex_lock(&platform_tx_mutex);
//    if (platform_tcp_fd > 0 && (exceptSocket.port != currSocket.port || strcmp(currSocket.domain_name, exceptSocket.domain_name))) {
//        DisconnectTCP(platform_tcp_fd);
//        platform_tcp_fd = -1;
//    } else if (platform_tcp_fd <= 0) {
//        ConnectPlatform(exceptSocket.domain_name, exceptSocket.port);
//    }
//    pthread_mutex_unlock(&platform_tx_mutex);
}
void PlatformStatusChanged(uint32_t event, const uint8_t *data, int length)
@@ -270,17 +270,43 @@
        return;
    DEBUG("连接RTK平台 %s: %d", domain_name, port);
    // TODO
    struct platformSocketInfo *ptr = (struct platformSocketInfo *)malloc(sizeof(struct platformSocketInfo));
    strcpy(ptr->domain_name, domain_name);
    ptr->port = port;
    if (ctp == NULL) {
        ctp = new CTcpPort();
    pthread_t platform_pid;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached
    pthread_create(&platform_pid, &attr, PlatformDataListenThread, ptr);
        ctp->set_event_callback(TcpEventCallback, NULL);
        ctp->set_data_callback(TcpDataCallback, NULL);
    }
    if (!ctp->IsOpen()) {
        ctp->OpenTcpPort(domain_name, port);
    } else if ((ctp->m_nPort != port || strcmp(ctp->m_sIp.c_str(), domain_name))) {
        ctp->CloseTcpPort();
    }
}
static void TcpEventCallback(int stat, void *p, void *context)
{
    CTcpPort *pTcpPort = (CTcpPort *)p;
    uint8_t buffer[256];
    strcpy((char *)buffer, pTcpPort->m_sIp.c_str());
    buffer[pTcpPort->m_sIp.length() + 1] = HI_UINT16(pTcpPort->m_nPort);
    buffer[pTcpPort->m_sIp.length() + 2] = LO_UINT16(pTcpPort->m_nPort);
    if (stat == 0) {
        PlatformStatusChanged(PLATFORM_CONNECT_EVT, buffer, pTcpPort->m_sIp.length() + 3);
    } else {
        PlatformStatusChanged(PLATFORM_DISCONNECT_EVT, buffer, pTcpPort->m_sIp.length() + 3);
    }
}
static void TcpDataCallback(void *buffer, int length, void *p, void *context)
{
    if (length > 0) {
        Parse(DATA_ACCESS_PLATFORM, (uint8_t *)buffer, length);
    }
}
static void ConnectPlatformLater(union sigval sig) {
@@ -306,8 +332,8 @@
{
    switch (events) {
        case PLATFORM_CONNECT_EVT: {
            DEBUG("平台连接成功 %s:%d", currSocket.domain_name, currSocket.port);
            MA_RtkPlatformConnect(1, currSocket.domain_name, currSocket.port);
            DEBUG("平台连接成功 %s:%d", data, BUILD_UINT16(data[strlen((char *)data) + 2], data[strlen((char *)data) + 1]));
            MA_RtkPlatformConnect(1, (char *)data, BUILD_UINT16(data[strlen((char *)data) + 2], data[strlen((char *)data) + 1]));
            platformStatus.connected = 1;
            if (!platformStatus.registed || platformStatus.platformKeyLength == 0) {
@@ -321,8 +347,8 @@
        }
        case PLATFORM_DISCONNECT_EVT: {
            DEBUG("平台断开 %s:%d", currSocket.domain_name, currSocket.port);
            MA_RtkPlatformConnect(0, currSocket.domain_name, currSocket.port);
            DEBUG("平台断开 %s:%d", data, BUILD_UINT16(data[strlen((char *)data) + 2], data[strlen((char *)data) + 1]));
            MA_RtkPlatformConnect(0, (char *)data, BUILD_UINT16(data[strlen((char *)data) + 2], data[strlen((char *)data) + 1]));
            AppTimer_delete(ConnectPlatformLater);
            AppTimer_add(ConnectPlatformLater, D_SEC(2));
@@ -660,7 +686,11 @@
            break;
        }
        case BLUETOOTH_DATA_EVT: {
            ParseMcu(data, length);
            if (Virtual2IsConnected()) {
            } else {
                ParseMcu(data, length);
            }
            break;
        }
        case SENSOR_CHANGE_EVT: {
@@ -672,76 +702,13 @@
    }
}
static void *PlatformDataListenThread(void *p) {
    struct platformSocket *ptr = (struct platformSocket *)p;
    uint8_t RxBuf[PARSE_BUFF_SIZE];
    int fds_ret;
    struct timeval tv;
    fd_set rdfds;
    fd_set exfds;
    int fd = -1;
    int RxBufLen = 0;
    fd = ConnectTCP(ptr->domain_name, ptr->port);
    pthread_mutex_lock(&platform_tx_mutex);
    platform_tcp_fd = fd;
    currSocket = *ptr;
    pthread_mutex_unlock(&platform_tx_mutex);
    if (fd > 0) {
        PlatformStatusChanged(PLATFORM_CONNECT_EVT, NULL, 0);
    }
    while (fd > 0) {
        tv.tv_sec = 5;
        tv.tv_usec = 0;
        FD_ZERO(&rdfds); //clean
        FD_SET(fd, &rdfds); //set
        fds_ret = select(fd + 1, &rdfds, NULL, NULL, &tv);
        if (fds_ret < 0) {
            break;
        } else if(fds_ret == 0) {
            //Occur failure(such as line disconnect)
        } else if(FD_ISSET(fd, &rdfds)) {
            RxBufLen = ReadTCP(fd, RxBuf, sizeof(RxBuf));
            if (RxBufLen < 0) {
                break;
            } else if (RxBufLen > 0) {
                Parse(DATA_ACCESS_PLATFORM, RxBuf, RxBufLen);
            }
        }
    }
    pthread_mutex_lock(&platform_tx_mutex);
    if (platform_tcp_fd > 0) {
        DisconnectTCP(platform_tcp_fd);
        platform_tcp_fd = -1;
    }
    pthread_mutex_unlock(&platform_tx_mutex);
    free(ptr);
    PlatformStatusChanged(PLATFORM_DISCONNECT_EVT, NULL, 0);
    pthread_exit(NULL);
}
int WritePlatform(const uint8_t * buf, uint32_t len)
{
    int ret = -1;
    pthread_mutex_lock(&platform_tx_mutex);
    if (platform_tcp_fd > 0) {
        ret = WriteTCP(platform_tcp_fd, buf, len);
    if (ctp != NULL && ctp->IsOpen()) {
        ret = ctp->WriteTCP(buf, len);
    }
    pthread_mutex_unlock(&platform_tx_mutex);
    return ret;
}
lib/src/main/cpp/test_common/car_sensor.cpp
@@ -16,7 +16,6 @@
static uint16_t gpioStore;
static int left_turn_signal, right_turn_signal;
static int flashMainBeamCnt;
enum {
    SENSOR_SEATBELT,
@@ -67,7 +66,7 @@
static void ChangeLRLight(int light);
static void ConfirmTurnSigalLater(union sigval sig);
static void flashBeamLightClose(union sigval sig);
static void confirmFlashBeamLightLater(union sigval sig);
static void SensorChanged(int id, int value);
void CarSensorInit(void)
@@ -83,7 +82,6 @@
    memset(&Sensor, 0, sizeof(Sensor));
    left_turn_signal = right_turn_signal = 0;
    flashMainBeamCnt = 0;
    pthread_mutex_init(&sonser_mutex, NULL);
    pthread_mutex_init(&status_rw_mutex, NULL);
@@ -272,15 +270,9 @@
    WriteCarStatus(FLASH_BEAM_LAMP, OFF_LIGHT);
}
static void confirmFlashBeamLightLater(union sigval sig)
{
    AppTimer_delete(confirmFlashBeamLightLater);
    flashMainBeamCnt = 0;
}
static void SensorChanged(int id, int value)
{
//    DEBUG("状态改变 %d = %d", id, value);
    DEBUG("状态改变 %d = %d", id, value);
    switch (id) {
        case SENSOR_LEFT_TURN_SIGNAL: {
            left_turn_signal = value;
@@ -335,21 +327,24 @@
            break;
        }
        case SENSOR_MAIN_BEAM_LIGHT: {
            static uint32_t t1 = 0;
            if (value == 0) {
                WriteCarStatus(MAIN_BEAM_LAMP, OFF_LIGHT);
            } else {
                WriteCarStatus(MAIN_BEAM_LAMP, MAIN_BEAM_LIGHT);
            }
            if (++flashMainBeamCnt > 3) {         // 亮-灭-亮-灭
                WriteCarStatus(FLASH_BEAM_LAMP, FLASH_BEAM_LIGHT);
            if (value != 0) {
                t1 = AppTimer_GetTickCount();
            } else if (AppTimer_GetTickCount() - t1 < D_SEC(3)) {
                // 3秒内完成亮灭,闪灯
                if (ReadCarStatus(FLASH_BEAM_LAMP) != FLASH_BEAM_LIGHT) {
                    WriteCarStatus(FLASH_BEAM_LAMP, FLASH_BEAM_LIGHT);
                }
                AppTimer_delete(flashBeamLightClose);
                AppTimer_add(flashBeamLightClose, D_SEC(2));
            }
            AppTimer_delete(confirmFlashBeamLightLater);
            AppTimer_add(confirmFlashBeamLightLater, D_SEC(3));
            break;
        }
        case SENSOR_SEATBELT: {
lib/src/main/cpp/test_items2/dummy_light.cpp
@@ -77,6 +77,7 @@
    AppTimer_delete(CheckSolution);
}
// 记录中间过程
void handleLigthExam(uint16_t id, int value)
{
    if (testing) {
@@ -90,10 +91,9 @@
    }
}
// 检查最终状态
static void CheckSolution(union sigval sig)
{
    int question = sig.sival_int;
    AppTimer_delete(CheckSolution);
    if (content[question].process.size() > 0) {
@@ -112,7 +112,7 @@
    }
    for (int i = 0; i < content[question].solution.size(); ++i) {
        if (ReadCarStatus((content[question].solution[i]>>8)&0xFF) != content[question].solution[i] & 0xFF) {
        if (ReadCarStatus((content[question].solution[i]>>8)&0xFF) != (content[question].solution[i] & 0xFF)) {
            AddExamFault(content[question].wrongCode, &currRtkTime);
            break;
        }
@@ -126,6 +126,7 @@
static void ExamDummyLight(void)
{
    if (testing && question < contentNum) {
        DEBUG("灯光题目: %s", content[question].tts.c_str());
        PlayTTS(content[question].tts, DummyLightTTSDone);
    } else {
        testing = false;