// // Created by YY on 2019/12/27. // #include #include #include #include #include #include #include "platform.h" #include "../jni_log.h" #include "../common/net.h" #include "../native-lib.h" #include "../common/apptimer.h" #include "parse_net.h" #include "../defs.h" #include "../rtk_module/rtk.h" #include "../mcu/mcu_if.h" #include "../master/comm_if.h" #include "../utils/xconvert.h" #include "../utils/num.h" #include "../driver_test.h" #include "../test_common/car_sensor.h" #include "../test_items2/stop_car.h" #include "../test_items2/operate_gear.h" #include "../test_items2/drive_straight.h" #define PARSE_BUFF_SIZE 4096 #define DEBUG(fmt, args...) LOGD(" <%s>: " fmt, __func__, ##args) struct platformSocket { char domain_name[32]; int port; }; static struct deviceInfo_ { uint16_t province; uint16_t city; uint8_t device_model[21]; uint8_t device_sn[17]; char imei[17]; }deviceInfo; struct platformSocketInfo { char domain_name[32]; int port; }; static struct platformStatus_ { uint8_t platformKey[64]; int platformKeyLength; uint32_t connected : 1; uint32_t registed : 1; uint32_t login : 1; uint32_t downloadRtk : 1; } platformStatus; struct event_t { uint32_t id; int length; void *data; }; static struct event_queue_t { struct event_t event; struct event_queue_t *next; } *eventQueue; struct platformSocket exceptSocket, currSocket; static sem_t sem_status_changed; static bool requestPlatformSendRtk = false; static int platform_tcp_fd = 0; static pthread_mutex_t platform_tx_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t events_mutex = PTHREAD_MUTEX_INITIALIZER; static struct gpsBrief gbf; static struct rtkBrief rbf; static void AddEvnet(uint32_t event, const uint8_t *data, int length); static struct event_t * FetchEvent(void); static void RemoveEvent(void); static void ReqRtkPlatformConfigTimeout(union sigval sig); 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); static void RegisterPlatform(void); static void RegisterPlatformTimeout(union sigval sig); static void LoginPlatform(void); 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) { DEBUG("AddEvnet 0x%04X length %d", event, length); struct event_queue_t *nw = (struct event_queue_t *)malloc(sizeof(struct event_queue_t)); nw->next = NULL; nw->event.id = event; nw->event.data = NULL; nw->event.length = 0; if (data != NULL && length > 0) { nw->event.data = malloc(length); nw->event.length = length; memcpy(nw->event.data, data, length); } pthread_mutex_lock(&events_mutex); struct event_queue_t *p = eventQueue; while (p != NULL && p->next != NULL) p = p->next; if (eventQueue == NULL) eventQueue = nw; else p->next = nw; pthread_mutex_unlock(&events_mutex); } static struct event_t * FetchEvent(void) { struct event_t *evp = NULL; pthread_mutex_lock(&events_mutex); struct event_queue_t *p = eventQueue; if (p != NULL) { evp = &p->event; } pthread_mutex_unlock(&events_mutex); return evp; } static void RemoveEvent(void) { void *p1 = NULL, *p2 = NULL; pthread_mutex_lock(&events_mutex); struct event_queue_t *p = eventQueue; if (p != NULL) { eventQueue = p->next; p1 = p; p2 = p->event.data; } pthread_mutex_unlock(&events_mutex); if (p2 != NULL) free(p2); if (p1 != NULL) free(p1); } void InitPlatform(const uint8_t *phone, const char *domain_name, int port) { DEBUG("InitPlatform"); memset(&gbf, 0, sizeof(gbf)); memset(&rbf, 0, sizeof(rbf)); 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); PlatformTxInit(); pthread_t pid; pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);//detached pthread_create(&pid, &attr, StatusListenThread, NULL); } static void ReqRtkPlatformConfigTimeout(union sigval sig) { AppTimer_delete(ReqRtkPlatformConfigTimeout); AppTimer_add(ReqRtkPlatformConfigTimeout, D_SEC(2)); MA_ReqRtkPlatformConfig(); } void ConfigPlatform(const rtk_platform_cfg_t *p) { DEBUG("配置RTK平台资讯"); AppTimer_delete(ReqRtkPlatformConfigTimeout); strcpy(exceptSocket.domain_name, p->domain_name); exceptSocket.port = p->port; deviceInfo.province = p->province; deviceInfo.city = p->city; strcpy((char *)deviceInfo.device_model, p->device_model); strcpy((char *)deviceInfo.device_sn, p->device_sn); strcpy(deviceInfo.imei, p->imei); SetPlatformTxPhoneNum(p->phone); platformStatus.registed = 0;//p->registered; platformStatus.platformKeyLength = strlen(p->password) / 2; if (platformStatus.platformKeyLength > 0) { ConvertString2Hex(platformStatus.platformKey, sizeof(platformStatus.platformKey), p->password); } else { 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); } void PlatformStatusChanged(uint32_t event, const uint8_t *data, int length) { AddEvnet(event, data, length); sem_post(&sem_status_changed); } static void ConnectPlatform(const char *domain_name, int port) { if (domain_name == NULL || strlen(domain_name) == 0 || port == 0) return; DEBUG("ConnectPlatform %s: %d", domain_name, port); // TODO struct platformSocketInfo *ptr = (struct platformSocketInfo *)malloc(sizeof(struct platformSocketInfo)); strcpy(ptr->domain_name, domain_name); ptr->port = 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, PlatformDataListenThread, ptr); } static void ConnectPlatformLater(union sigval sig) { AppTimer_delete(ConnectPlatformLater); ConnectPlatform(exceptSocket.domain_name, exceptSocket.port); } static void *StatusListenThread(void *p) { while (true) { sem_wait(&sem_status_changed); struct event_t *evp = FetchEvent(); if (evp != NULL) { PlatformChangeEntry(evp->id, (uint8_t *)evp->data, evp->length); } RemoveEvent(); } } 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); platformStatus.connected = 1; if (!platformStatus.registed || platformStatus.platformKeyLength == 0) { RegisterPlatform(); } else if (!platformStatus.login) { LoginPlatform(); } } if (events & 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)); platformStatus.login = 0; platformStatus.connected = 0; AppTimer_delete(TriggerHeartbeat); AppTimer_delete(RegisterPlatformTimeout); AppTimer_delete(LoginPlatformTimeout); } 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; } MA_RtkPlatformRegister(data[0], data + 1, length - 1); } if (events & PLATFORM_LOGIN_EVT) { DEBUG("PLATFORM_LOGIN_EVT"); if (data[0] == 0) { platformStatus.login = 1; requestPlatformSendRtk = true; AppTimer_delete(TriggerHeartbeat); AppTimer_add(TriggerHeartbeat, D_SEC(30)); } else { platformStatus.login = 0; } MA_RtkPlatformLogin(data[0]); } if (events & GPS_UPDATE_EVT) { DEBUG("GPS_UPDATE_EVT length %d", length); 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); } // MA_SendGpsBrief(&brief); RequestRtkDownload(gps, 1); DEBUG("GPS_UPDATE_EVT ================"); } if (events & RTK_UPDATE_EVT) { DEBUG("RTK_UPDATE_EVT length %d", length); 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); } UpdateRTKInfo(rtk); 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; 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); MA_SendMcuBrief(&brief); // UpdateSensor(brief.gpio, brief.speed, brief.engine); } if (events & 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.lock = 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); 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 = (double)(BUILD_UINT16(data[15], data[14])) / 10.0; 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.lock = 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++]; UpdateSensor(&sensor); } if (events & CARD_UPDATE_EVT) { DEBUG("CARD_UPDATE_EVT length %d", length); int ret = -1; 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); } if (events & PLAY_TTS_DONE_EVT) { DummyLightTTSDone(*((int *)data)); StopCarTTSDone(*((int *)data)); OperateGearTTSDone(*((int *)data)); DriveStraightTTSDone(*((int *)data)); } } 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); } pthread_mutex_unlock(&platform_tx_mutex); return ret; } static void RegisterPlatformTimeout(union sigval sig) { DEBUG("RegisterPlatformTimeout"); AppTimer_delete(RegisterPlatformTimeout); RegisterPlatform(); } static void RegisterPlatform(void) { AppTimer_delete(RegisterPlatformTimeout); AppTimer_add(RegisterPlatformTimeout, D_SEC(15)); SendDeviceRegister(deviceInfo.province, deviceInfo.city, deviceInfo.device_model, strlen((char *)deviceInfo.device_model), deviceInfo.device_sn, deviceInfo.imei); } static void TriggerHeartbeat(union sigval sig) { AppTimer_delete(TriggerHeartbeat); if (platformStatus.login && platformStatus.connected) { SendHeartBeat(DATA_ACCESS_PLATFORM); AppTimer_add(TriggerHeartbeat, D_SEC(30)); } } static void LoginPlatformTimeout(union sigval sig) { AppTimer_delete(LoginPlatformTimeout); LoginPlatform(); } static void LoginPlatform(void) { uint32_t tim = time(NULL); uint8_t data[12]; uint8_t *ciphertext; data[0] = BREAK_UINT32(tim, 3); data[1] = BREAK_UINT32(tim, 2); data[2] = BREAK_UINT32(tim, 1); data[3] = BREAK_UINT32(tim, 0); AppTimer_delete(LoginPlatformTimeout); AppTimer_add(LoginPlatformTimeout, D_SEC(15)); DESEncrypt(platformStatus.platformKey, platformStatus.platformKeyLength, data, 4, &ciphertext); if (ciphertext != NULL) { memcpy(data + 4, ciphertext, 8); SendDeviceLogin(data, sizeof(data)); } } void DeviceRegisterCallback(uint8_t res, const uint8_t *data, int length) { uint8_t az[16]; AppTimer_delete(RegisterPlatformTimeout); az[0] = res; if (res == 0) { memcpy(az+1, data, length); PlatformStatusChanged(PLATFORM_REGISTER_EVT, az, length + 1); } else { PlatformStatusChanged(PLATFORM_REGISTER_EVT, az, 1); } } void DeviceLoginCallback(uint8_t res) { uint8_t az; AppTimer_delete(LoginPlatformTimeout); az = res; PlatformStatusChanged(PLATFORM_LOGIN_EVT, &az, 1); } void ReceivedRtk(const uint8_t *data, int length) { DEBUG("ReceivedRtk length %d", length); AppTimer_delete(RequestRtkNoResp); // 汇报给单片机 if (length > 0) { SendRtkToMcu(data, length); } } static void RequestRtkNoResp(union sigval sig) { AppTimer_delete(RequestRtkNoResp); requestPlatformSendRtk = true; } void RequestRtkDownload(const gpsStatus_t *gps, uint16_t rtk_pkt_interval) { if (requestPlatformSendRtk && gps->gps_status > 0) { DEBUG("请求下载RTK数据"); requestPlatformSendRtk = false; AppTimer_delete(RequestRtkNoResp); AppTimer_add(RequestRtkNoResp, D_SEC(5)); uint32_t latitude = (uint32_t)(gps->latitude * 1000000); uint32_t longitude = (uint32_t)(gps->longitude * 1000000); int altitude = (int) fabs(gps->altitude); uint8_t bcd_time[6]; bcd_time[0] = ((gps->YY/10)<<4) + (gps->YY%10); bcd_time[1] = ((gps->MM/10)<<4) + (gps->MM%10); bcd_time[2] = ((gps->DD/10)<<4) + (gps->DD%10); bcd_time[3] = ((gps->hh/10)<<4) + (gps->hh%10); bcd_time[4] = ((gps->mm/10)<<4) + (gps->mm%10); bcd_time[5] = ((gps->ss/10)<<4) + (gps->ss%10); SendRTKStart(latitude, longitude, altitude, bcd_time, rtk_pkt_interval); } } void StopRtkDownload(void) { SendRTKStop(); }