// // Created by YY on 2019/12/27. // #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" #define PARSE_BUFF_SIZE 4096 const char *VK_REG = "platform_register"; 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[16]; }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 platformSocket exceptSocket, currSocket; static uint32_t eventMask; 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 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 RegisterPlatform(void); static void RegisterPlatformTimeout(union sigval sig); static void LoginPlatform(void); static void LoginPlatformTimeout(union sigval sig); static void TriggerHeartbeat(union sigval sig); void InitPlatform(const uint8_t *phone, const char *domain_name, int port) { pthread_mutex_init(&platform_tx_mutex, NULL); pthread_mutex_init(&events_mutex, NULL); eventMask = 0; platform_tcp_fd = -1; memset(&currSocket, 0, sizeof(currSocket)); strcpy(exceptSocket.domain_name, domain_name); exceptSocket.port = port; sem_init(&sem_status_changed, 0, 0); strcpy(deviceInfo.imei, GetImei()); deviceInfo.province = 53; deviceInfo.city = 100; strcpy((char *)deviceInfo.device_model, "RTKBaseStation"); strcpy((char *)deviceInfo.device_sn, "2019101500000001"); PlatformTxInit(phone); 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); strcpy(deviceInfo.imei, GetImei()); ConnectPlatform(domain_name, port); } void PlatformStatusChanged(uint32_t event) { pthread_mutex_lock(&events_mutex); eventMask |= event; pthread_mutex_unlock(&events_mutex); sem_post(&sem_status_changed); } static void ConnectPlatform(const char *domain_name, int port) { 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); char out[64]; sprintf(out, "连接平台 %s:%d...", domain_name, port); DisplayText(out); } 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); uint32_t events; pthread_mutex_lock(&events_mutex); events = eventMask; eventMask = 0; pthread_mutex_unlock(&events_mutex); if (events & PLATFORM_CONNECT_EVT) { char out[64]; sprintf(out, "平台连接成功 %s:%d", currSocket.domain_name, currSocket.port); DisplayText(out); platformStatus.connected = 1; if (!platformStatus.registed || platformStatus.platformKeyLength == 0) { RegisterPlatform(); } else if (!platformStatus.login) { LoginPlatform(); } } if (events & PLATFORM_DISCONNECT_EVT) { char out[64]; sprintf(out, "平台断开 %s:%d", currSocket.domain_name, currSocket.port); DisplayText(out); 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.platformKeyLength = GetPlatformKey(platformStatus.platformKey); platformStatus.registed = GetSharedValue(VK_REG); platformStatus.login = 0; DEBUG("platformStatus.platformKeyLength = %d", platformStatus.platformKeyLength); if (platformStatus.registed && platformStatus.platformKeyLength > 0) { LoginPlatform(); } } if (events & PLATFORM_LOGIN_EVT) { DEBUG("PLATFORM_LOGIN_EVT"); platformStatus.login = 1; requestPlatformSendRtk = true; AppTimer_delete(TriggerHeartbeat); AppTimer_add(TriggerHeartbeat, D_SEC(30)); } } } 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); } 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); 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) { AppTimer_delete(RegisterPlatformTimeout); if (res != 0) { } else { TextSpeak("终端注册成功"); DisplayText("终端注册成功"); SetPlatformKey(data, length); SetSharedValue(VK_REG, 1); PlatformStatusChanged(PLATFORM_REGISTER_EVT); } } void DeviceLoginCallback(uint8_t res) { AppTimer_delete(LoginPlatformTimeout); if (res != 0) { } else { TextSpeak("终端登录成功"); DisplayText("终端登录成功"); PlatformStatusChanged(PLATFORM_LOGIN_EVT); } } void RequestRtkDownload(uint32_t latitude, uint32_t longitude, uint16_t altitude, const uint8_t *bcd_time, uint16_t rtk_pkt_interval) { if (requestPlatformSendRtk) { requestPlatformSendRtk = false; SendRTKStart(latitude, longitude, altitude, bcd_time, rtk_pkt_interval); } } void StopRtkDownload(void) { SendRTKStop(); }