#include "stdio.h" #include <stdlib.h>
#define NET_PACKET_DATA_SIZE 1024 //估计一包的大小暂时为1k #define NET_PACKET_SIZE (sizeof(NetPacketHeader) NET_PACKET_DATA_SIZE) * 100
typedef struct { unsigned char data[NET_PACKET_DATA_SIZE]; //format sockaddr_in cliaddrIP udp packet
}One_RecvdPacket; //一包数据
typedef struct { char data[NET_PACKET_DATA_SIZE];//format sockaddr_in cliaddrIP bool crcresult const unsigned char* pDataBuffer, unsigned short nDataSize,
}One_SendPacket; //一包数据
typedef struct { char data[NET_PACKET_DATA_SIZE];
}One_InsertSql; //write sql text
/ 网络数据包包头 //struct NetPacketHeader //{ //unsigned shortwDataSize;///< 数据包的大小包括封包头和封包数据 //unsigned shortwOpcode;///< 操作码 //}; // / 网络数据包 //struct NetPacket //{ //NetPacketHeaderHeader;///< 包头 //unsigned charData[NET_PACKET_DATA_SIZE];///< 数据 //}; //typedef struct //{ //}B;
/// 网络数据包包头 typedef struct ///物理链路1Bytes协议版本1Bytes帧长2Bytes { unsigned char net_type; unsigned char doc_ver; char UDID[6]; char crcres[4]; unsigned short frame_datalen; }NetPacketHeader;
/// 网络数据包 typedef struct { NetPacketHeaderHeader;///< 包头 unsigned char Data[NET_PACKET_DATA_SIZE];///< 业务数据区 }NetPacket;
//
/// 网络操作码 enum eNetOpcode { NET_TEST1 = 1, CMD_NET_HEARTBEAT = 0x0010, //心跳数据 CMD_NET_LOGIN = 0x0012, //2.3.2终端登录请求-0X0012 CMD_NET_EXP_LOGIN = 0x0013, //2.3.3终端异常登录请求-0X0013 CMD_NET_DEVICEID_INFO = 0x0015, //2.3.4终端器件ID信息数据-0X0015 CMD_NET_STATUS_REPORT = 0x0017, //2.3.5终端待机请求/状态报告-0X0017 CMD_NET_WEB_INFO = 0x0019,//2.3.6终端车辆设备网络接口信息-0X0019 CMD_NET_SENSOR_DATA = 0x0020,//2.3.7终端传感器数据-0X0020 CMD_NET_GPS_DATA = 0x0022,//2.3.8终端定位数据-0X0022 CMD_NET_DIAGNOSIS_DATA = 0x0030, //诊断数据 }; enum eGPSway 定位方式:1 字节,0x01 = GPS标准定位,0x02 = GPS精简定位,0x05 = 基站定位。 { GPS_STRDAND =0x01, GPS_SIMPLE =0x02, GPS_BASE =0x05, }; /// 测试1的网络数据包定义 //struct NetPacket_Test1 //{ //intnIndex; //chararrMessage[512]; //}; typedef struct //DPU_String :<长度字节> <字符串> { unsigned short uLen;///双字节数字,指定字符串长度(包括\0’字符)。 char data;///业务数据内容1字节 }Heart_Beat;
typedef struct //DPU_String :<长度字节> <字符串> { unsigned short uLen;///双字节数字,指定字符串长度(包括\0’字符)。 char data[512]//字符串 }DPU_String;
// struct DPU_String //DPU_String :<长度字节> <字符串> // { // unsigned short uLen;///双字节数字,指定字符串长度(包括\0’字符)。 // char * pdata;//字符串,可变数组的大小 // // DPU_String():uLen(0),pdata(NULL) // { // // } // ~DPU_String() // { // if (pdata!=NULL) // { // free(pdata); // printf("~DPU_String memory release\n");//char *Ptr = NULL; Ptr = (char *)malloc(100 * sizeof(char)); // code... free(Ptr); Ptr // &bsp; } // } // }; //以下每一条业务serviceID对应一个结构体,整个业务数据包对应一条RCU 数据记录,也有一个相应结构体
typedef struct {
DPU_String Device_type; DPU_String Hardware_ver; DPU_String Software_ver; DPU_String Car_language; DPU_String Car_name; DPU_String Car_ver; char Vendor_name[12]; char Device_serial[12]; char Device_IMEI[15]; char SIM_num[20]; char Crypt_txt[32];
}Struct_Login_Info;
typedef struct { DPU_String Device_type; char Device_serial[12]; char Device_IMEI[15]; char SIM_num[20]; char Crypt_txt[32];
}Exp_Login;
typedef struct { char vin_code[17]; //0X0300 unsigned short carspeed; //0X0301 车速 unsigned short motorspeed; //0X0302 发动机转速 float cur_oilwear;//0X0303 瞬时油耗
float avg_oilwear;//0X0304 平均油耗 unsigned char key_info; //0X0305 钥匙信息 1 U8 float mileage_fault; // 0X030E 带故障行驶里程 4 float km unsigned int cur_mileage ; //0X0310 当前里程 float oil_temperature; //0X0311 油温 4 float
unsigned char oil_remain; //0X0312 剩余油量 1 U8 %
unsigned int mileage_remain; //0X0313 剩余里程 unsigned short journey_count; // 旅程次数 2 U16 unsigned short fire_count; //点火次数 2 U16
float air_pressure; // 0X0314 大气压 4 float float carout_temperature; //0X0316 车外温度 4 float float carin_temperature;// 0X0317 车内温度 4 float unsigned int MIL_infolight; //0X0319 MIL 信号灯 4 U8 float left_front_tire_press; //0X0320 左前轮胎压 4 float float left_back_tire_press; // 0X0321 左后轮胎压 4 float float right_front_tire_press; //0X0322 左前轮胎压 4 float float right_back_tire_press; //0X0323 左前轮胎压 4 float
unsigned short gasbag_info; //0X03A0 气囊信息 unsigned short seatbelt_info; // 0X03A1 安全带信息 unsigned short car_door_info; //0X03A2 车门信息 2 U16 unsigned short car_win_info; //0X03A3 车窗信息 2 U16 unsigned char turn_light_info; //0X03A4 方向灯信息 1 U8 unsigned char brake_info; //0X03B2 刹车信息 1 U8 unsigned char gear_info; //0X03DA 挡位信息 // 支持PIDs 可变可多包发送 // 读故障码 可变可多包发送 }Diagnosis_Data;
typedef struct { //<date>,<time>,<lat>,<long>,<alt>,<uncertainty> char date[20]; char time[20]; char lat_info[20]; char long_info[20]; int alt_info; int uncertainty; }GPS_DataBase;
typedef struct {
unsigned short timezone; // 619 timezone unsigned short ms; unsigned short year; unsigned short month; unsigned short day; unsigned short hour; unsigned short minute; unsigned short sencond;
}Timestamp;
//GPS 位置信息数据长度不定,格式为: // <UTC 时间>,<定位有效性>,<纬度>,<北纬或南纬>,<经度>,<东经或西经>,<速度>,<方位角>,<UTC 日期>,<GPS 状态>,<.HDOP>,<海拔高度>,<定位模式> ,<有效卫星个数> // // 解释: // UTC 时间为6-10 字节,UTC 时间,hhmmss.XXX(时分秒.毫秒)格式;(GPRMC 数据)。 // 定位有效性为1 字节,A=有效定位,V=无效定位(GPRMC 数据)。 // 纬度一般为9 字节,格式为:2232.1234,22 为度,32.1234 为分(GPRMC 数据)。ddmm.mmmm // 北纬或南纬为一字节,N 或S(GPRMC 数据)。 // 经度一般为10 字节,格式为11345.1234,113 为度,45.1234 为分(GPRMC 数据)。dddmm.mmmm // 东京或西经为1 字节,E 或W(GPRMC 数据)。 // 速度为浮点数,单位为海里,000.0~999.9 节,前面的0 也将被传输(GPRMC 数据)。 // 方位角为浮点数,范围000.0~359.9 度,以正北为基准,前面的0 也将被传输(GPRMC 数据)。 // UTC 日期为6 字节,ddmmyy(日月年)格式 (GPRMC 数据)。 // GPS 状态为1 字节,0=未定位,1=非差分定位,2=差分定位,6=正在估算(GPGGA 数据)。 // 有效卫星个数,可见讯号的卫星的总数,00 至 12(GPGSV 数据)。 // 海拔高度,单位为米,范围为-9999.9~99999.9,(GPGGA 数据)。 // HDOP,水平精度因子,范围0.5~99.9,数字越大表明误差越大,99.9 表明未定位(GPGGA 数据)。 // 定位模式1 字节,1 = 未定位, 2 = 二维定位, 3 = 三维定位。(GPGSA 数据)
typedef struct {
//<date>,<time>,<lat>,<long>,<alt>,<uncertainty> unsigned short UTC_time[4]; //UTC_time[0] UTC_time[1] UTC_time[2]时UTC_time[3]分秒.毫秒 char posvalid; //定位有效性 float weidu[2]; //纬度 weidu[0]度/ weidu[1]分 char beiwei; float jingdu[2]; //经度 jingdu[0]度/ jingdu[1]分 char dongjing; //东经或西经 float speed; float direction_angle; int UTC_date[3]; //day/month/year UTC_date[0] UTC_date[1] UTC_date[2] char GPS_status; //GPS 状态为1 字节,0=未定位,1=非差分定位,2=差分定位,6=正在估算(GPGGA 数据)。 float HDOP ; float high; char posmodel; //定位模式1 字节,1 = 未定位, 2 = 二维定位, 3 = 三维定位 unsigned short star_num; //有效卫星个数,可见讯号的卫星的总数,00 至 12(GPGSV 数据)。
}GPS_DataStandard;
/.cpp
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/socket.h> #include<netinet/in.h> #include<pthread.h> #include<arpa/inet.h> #include<sys/types.h> #include<sys/time.h> #include<errno.h>
#include <stdbool.h> #include "NetDefine.h" #include "/usr/include/mysql/mysql.h"
extern "C" //c文件与c++文件混合编程 { #include "crc.h" }
#include <list> using namespace std;
#define BUFFSIZE 1024 #define PORT 9100 #define BACKLOG 5 #define MAXFD 5
list<One_InsertSql> g_recordlist_write_SQL;//list<Struct_Login_Info> g_recordlist_write_SQL;//暂时指登陆信息,之后是指写入数据库的一条记录,来自设备的整包业务数据
list<One_RecvdPacket> g_ReceviedDataList; list<One_SendPacket> g_readySendDataList;
pthread_mutex_t mutex_logininfo=PTHREAD_MUTEX_INITIALIZER;//CRITICAL_SECTION g_cs_logininfo ; pthread_mutex_t g_mutex_recevieddata=PTHREAD_MUTEX_INITIALIZER;//CRITICAL_SECTION g_cs_logininfo ; pthread_mutex_t g_mutex_senddata=PTHREAD_MUTEX_INITIALIZER;//CRITICAL_SECTION
//list<int> g_list2; MYSQL *mysql_conn; int g_server_sock;
void doClientRequest(int server_sock); void * doClientThread(void *pParam); void OnServiceData(sockaddr_in cliaddrIP ,const unsigned char* pDataBuffer, unsigned short nDataSize ); bool OnServiceIDMessage( long long udid,const unsigned short nOpcode,const unsigned char* pDataBuffer, unsigned short nDataSize ) ; // by yand void ToHex( char * src, int length, char * dst ); void get_client_IP(int clientsock); unsigned short TwoByte2short(char *p); void put_record(One_InsertSql writesql); //写一条数据到链表 bool get_record(One_InsertSql * writesql); //从链表读取一条数据写入数据库
bool CrcCheckData(const unsigned char* pDataBuffer, unsigned short nDataSize); Timestamp get_timestamp(unsigned char *pdata,int len ); unsigned char Find_char_add_len(unsigned char *indata,int *gps_datalen,unsigned char *gprs_straddr[]); uint32_t gprs_data_crc32(uint8_t * indata,uint16_t len);
void mysql_connect(); void mysql_disconnect(); void * WriteMysqlThread(void *pParam) ; void * HandleDataThread(void *pParam) ; void * SendtoRCUThread(void *pParam) ; void mysql_connect() { char *server = "192.168.16.111"; //"127.0.0.1"; //192.168.78.130//"localhost"; char *user = "yandong"; //root char *password = "123456"; //"mysql"; /* 此处改成你的密码 */ char *database = "test"; mysql_conn = mysql_init(NULL); /* Connect to database */ //if (mysql_real_connect(conn, server,user, password, database, 0, NULL, 0)){ //localhost port=0 if (mysql_real_connect(mysql_conn, server,user, password, database, 0, NULL, 0)) { printf("mysql success connect\n"); } } void mysql_disconnect() { mysql_close(mysql_conn); } void *WriteMysqlThread(void *pParam) //独立数据库写线程 { int temp=(int)pParam; MYSQL_RES *res; MYSQL_ROW row; while(1) { One_InsertSql onesql; bool bres=get_record(&onesql); if (true == bres)//取得记录了 { /* send SQL query */ char chsql[1000]; // char Vendor_name[12+1]; // char Device_serial[12+1]; // char Device_IMEI[15+1]; // char SIM_num[20+1]; // char Crypt_txt[32+1];//最后一个字节默认初始就是'\0' // memset(Vendor_name,0,sizeof(Vendor_name)); // memset(Device_serial,0,sizeof(Device_serial)); // memset(Device_IMEI,0,sizeof(Device_IMEI)); // memset(SIM_num,0,sizeof(SIM_num)); // memset(Crypt_txt,0,sizeof(Crypt_txt)); // memcpy(Vendor_name,lf.Vendor_name,sizeof(lf.Vendor_name)); // memcpy(Device_serial,lf.Device_serial,sizeof(lf.Device_serial)); // memcpy(Device_IMEI,lf.Device_IMEI,sizeof(lf.Device_IMEI)); // memcpy(SIM_num,lf.SIM_num,sizeof(lf.SIM_num)); // memcpy(Crypt_txt,lf.Crypt_txt,sizeof(lf.Crypt_txt)); // sprintf(chsql,"insert into login_info (device_type,hardware_ver,software_ver,car_lan,car_name,car_ver,vendor_name, \ // dev_serial,dev_IMEI,SIM_num,cry_txt) \ // values ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')",lf.Device_type.data,lf.Hardware_ver.data,lf.Software_ver.data, \ // lf.Car_language.data,lf.Car_name.data,lf.Car_ver.data, \ // Vendor_name, Device_serial,Device_IMEI,SIM_num,Crypt_txt); // printf("chsql:%d,%s\n",strlen(chsql),chsql);
if ( mysql_query(mysql_conn, onesql.data) ) { fprintf(stderr, "insert :%s\n", mysql_error(mysql_conn)); return NULL; } else { printf("insert success rows:%lu\n",(ulong)mysql_affected_rows(mysql_conn)); }
// res=mysql_use_result(mysql_conn); // printf("MySQL Tables in mysql databases:\n"); // while((row=mysql_fetch_row(res))!=NULL) // printf("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s \n",row[0],row[1],row[2],row[3],row[4],row[5],row[6],row[7],row[8],row[9],row[10]);
// } //sleep(1); //停留1秒 usleep(1000*100); //停留1秒 ,这里是设置写记录数据库的频率,如果慢把时间设置减少 /* send SQL query */ }
}
void put_record(One_InsertSql writesql)//(Struct_Login_Info login_info) { //Lock(cs); pthread_mutex_lock(&mutex_logininfo); g_recordlist_write_SQL.push_back(writesql); pthread_mutex_unlock(&mutex_logininfo); //unLock(cs); } bool get_record(One_InsertSql * writesql) { bool bres=false;
pthread_mutex_lock(&mutex_logininfo); //Lock(cs); // if (g_recordlist_write_SQL.size() <=0) //没记录 // { // // bres=false; // //return bres;//别在这返回,最后解锁然后返回,别忘解锁pthread_mutex_unlock // }
for (list<One_InsertSql>::iterator it = g_recordlist_write_SQL.begin(); it != g_recordlist_write_SQL.end(); ++it) { One_InsertSql InsertSql=*it; memcpy(writesql,&InsertSql,sizeof(One_InsertSql)); bres=true; break;//只取前面第一条 } if(true == bres ) { g_recordlist_write_SQL.pop_front(); //从链表头取出一条后,杀掉这条 } pthread_mutex_unlock(&mutex_logininfo); //unLock(cs); return bres; }
// 输出一个链表 //void ShowList(list<int>& listTemp) //{ // // size()返回链表中元素个数 // cout << listTemp.size() << endl; // for (list<int>::iterator it = listTemp.begin(); it != listTemp.end(); ++it) // { // cout << *it << ' '; // } // cout << endl; //}
int main(void) { int server_sock,client_sock,result,len,para; struct sockaddr_in serveraddr; pthread_t pt;
if((server_sock=socket(AF_INET,SOCK_DGRAM,0))<0) //udp { perror("server socket:"); exit(-1); } g_server_sock = server_sock;
puts("server socket is OK!"); bzero(&serveraddr,sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_addr.s_addr=htonl(INADDR_ANY); serveraddr.sin_port=htons(PORT); len=sizeof(serveraddr);
int opt = 1; setsockopt(server_sock,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); //address already in use problem if((result=bind(server_sock,(struct sockaddr*)&serveraddr,sizeof(serveraddr)))<0) { perror("server bind:"); exit(-1); } printf("server bind is OK!server_sock:%d \n",server_sock);
all below threads//
// below is recv data thread// if((result=pthread_create(&pt,NULL,doClientThread,(void *)&server_sock))!=0) //recv all udp data thread { perror("pthread recv data create fail:\n"); exit(-1); }else { printf("recv data thread create success.....\n"); } //below is handle data thread if((result=pthread_create(&pt,NULL,HandleDataThread,(void *)&server_sock))!=0) //handle all udp data thread { perror("pthread handle data create fail:\n"); exit(-1); }else { printf("handle data thread create success.....\n"); }
//below is mysql write udp data thread pthread_t pwsql; mysql_connect();//sql init and connect if((result=pthread_create(&pwsql,NULL,WriteMysqlThread,NULL ) )!=0) //独立写mysql数据库线程 { perror("pthread WriteMysqlThread create fail:"); exit(-1); }else {
printf("mysql thread create success.....\n"); } /below is send respose udp packet to RCU thread/
//void * SendtoRCUThread(void *pParam) if((result=pthread_create(&pt,NULL,SendtoRCUThread,(void *)&server_sock))!=0) //handle all udp data thread { perror("pthread SendtoRCUThread create fail:\n"); exit(-1); }else { printf(" SendtoRCUThread create success.....\n"); }
//
while (1) // main thread { sleep(1); // sleep 1 s }
// printf("%d create thread ok\n",client_sock); // //char ip[20]; // printf("connect "); // get_client_IP(client_sock);//print the client IP // //printf("connect client IP:%s\n",ip); // } // exit(0); }
void * HandleDataThread(void *pParam) //handle service data thread when the list data buffer is not null {
while(1) { usleep(1000); // 1ms
bool bget=false;
One_RecvdPacket recvpacket;
pthread_mutex_lock(&g_mutex_recevieddata); //Lock(cs); //get one record data from list buffer queue
for (list<One_RecvdPacket>::iterator it = g_ReceviedDataList.begin(); it != g_ReceviedDataList.end(); ++it) { recvpacket=*it; //memcpy(plogin_info,&recvpacket,sizeof(One_RecvdPacket)); bget=true; break;//只取前面第一条 } if(true == bget ) { g_ReceviedDataList.pop_front(); //从链表头取出一条后,杀掉这条 }
pthread_mutex_unlock(&g_mutex_recevieddata);
if (false == bget) // if g_ReceviedDataList size is null , so can't get data { //printf("can't get one record data from g_ReceviedDataList.......\n"); continue;
}else // handle data part {
struct sockaddr_in cliaddr;
memcpy(&cliaddr,recvpacket.data,sizeof(cliaddr));
unsigned char *udpdata=recvpacket.data+sizeof(cliaddr); NetPacketHeader* pHead = (NetPacketHeader*) (udpdata);
unsigned char *pdata=udpdata; //printf pHead printf("net_type:%c,doc_ver:%c,frame_datalen:%d\n",pHead->net_type,pHead->doc_ver,pHead->frame_datalen); //struct NetPacketHeader //物理链路1Bytes 协议版本1Bytes 帧长2Bytes
const unsigned short nPacketSize = sizeof(NetPacketHeader)+pHead->frame_datalen; //整个完整一包数据大小,包含包头 //const unsigned short nDataSize = nPacketSize - (unsigned short)sizeof(NetPacketHeader); // printf("data start....\n\n\n"); // printf("nPacketSize:%d \n",nPacketSize); // for(int i=0;i<nPacketSize;i++) // { // printf("%x ",*pdata++); // if(i%16==0) // { // printf("\n"); // } // } // printf("\n"); // exit(0);
//struct sockaddr_in servaddr, cliaddr; OnServiceData(cliaddr,pdata, nPacketSize); //nDatasize
}
}
} void doClientRequest(int server_sock) //recv data thread {
int nRecvsize=0; socklen_t len; unsigned char mesg[NET_PACKET_SIZE]; //struct sockaddr_in *pcliaddr;//segmentaion fault ---null point problems socklen_t clilen; struct sockaddr_in servaddr, cliaddr; clilen=sizeof(cliaddr);
for(;;) {
/* waiting for receive data */ printf("ready recv data...server_sock:%d\n",server_sock); nRecvsize = recvfrom(server_sock, mesg, NET_PACKET_SIZE, 0,(struct sockaddr *) &cliaddr, &clilen); //problems //sendto(server_sock, mesg, nRecvsize, 0, (struct sockaddr *)&cliaddr, clilen); // printf("recvfrom data start....\n\n\n"); // printf("nPacketSize:%d \n",nRecvsize); // unsigned char *p=(unsigned char *)mesg; // for(int i=0;i<nRecvsize;i++) // { // printf("%x ",*p++); // if(i%16==0) // { // printf("\n"); // } // } // printf("\n"); // sendto(server_sock, mesg, nRecvsize, 0, (struct sockaddr *)&cliaddr, clilen); // continue; //exit(0); /* sent data back to client */ //get ip //char temip[20]; //printf("1\n"); //printf("2\n"); char *tempip=NULL; //sockaddr_in* ps=(sockaddr_in*)&cliaddr; printf("s_addr:%d\n",cliaddr.sin_addr.s_addr); tempip = inet_ntoa(cliaddr.sin_addr); //char tempip[32]={0}; if ( NULL== (char*) (inet_ntop(AF_INET,&ps->sin_addr.s_addr,tempip,31)) ) { printf("inet_ntop error\n" ); } //sprintf(buf_log,"received a connection from %s\n", str);
//printf("3\n"); int port = ntohs(cliaddr.sin_port); //printf("4\n"); printf("ip:%s:%d,len:%d,data:%s\n",tempip,port,nRecvsize,mesg); One_RecvdPacket recvpacket; memcpy(recvpacket.data,&cliaddr,sizeof(cliaddr));//head cliaddr part memcpy(recvpacket.data+sizeof(cliaddr), mesg, nRecvsize);
pthread_mutex_lock(&g_mutex_recevieddata); //Lock(cs); //插入数据到包队列里
g_ReceviedDataList.push_back(recvpacket); printf("insert one recv packet to list.....\n"); pthread_mutex_unlock(&g_mutex_recevieddata); //Lock(cs);
//sendto(sockfd, mesg, n, 0, pcliaddr, len); }
pthread_detach(pthread_self()); printf("pthread_detach pthread_self()...\n"); }
// // char buff[BUFSIZ]; // int result; // fd_set readfd;//,writefd; // struct timeval tv; // tv.tv_sec=1; // tv.tv_usec=0; // // char m_cbRecvBuf[NET_PACKET_SIZE]; //接收区为大约10包网络数据大小内存 // char m_cbDataBuf[NET_PACKET_SIZE]; //缓冲区为大约10包网络数据大小内存 // int m_nRecvSize = 0; // memset( m_cbRecvBuf, 0, sizeof(m_cbRecvBuf) ); // memset( m_cbDataBuf, 0, sizeof(m_cbDataBuf) ); // // for(;;) // { // bzero(buff,sizeof(buff)); // FD_ZERO(&readfd); // //FD_ZERO(&writefd); // //FD_SET(0,&readfd);//检测键盘输入 // FD_SET(client_sock,&readfd); // if((result=select(client_sock+1,&readfd,NULL,NULL,&tv))==-1)//开始等待输入输出操作 // { // perror("server select:"); // exit(-1); // }else if(result==0){ // //printf("have no message comming\n"); // continue; // }else{ // printf("message comming...\n"); // // if(FD_ISSET(0,&readfd)) // // { // // /*用户按键事件响应*/ // // fgets(buff,sizeof(buff),stdin); // // if(!strncasecmp(buff,"quit",4)) // // { // // printf("%d client customer exit chat\n",client_sock); // // break; // // } // // result=send(client_sock,buff,strlen(buff)+1,0); // // if(result>0) // // { // // printf("send %d byte\n%s\n",result,buff); // // } // // else{ // // printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",buff, errno, strerror(errno)); // // break; // // } // // } // if(FD_ISSET(client_sock,&readfd)) //client data coming // { // // 接收数据 // int nRecvSize = recv(client_sock,m_cbRecvBuf+m_nRecvSize, sizeof(m_cbRecvBuf)-m_nRecvSize, 0); // if (nRecvSize <= 0) //客服端关闭或者网络出错 // { // close(client_sock); // printf("when recv,server is off connect\n"); // printf("exit recv data thread......\n"); // //char ip[20]; // //get_client_IP(client_sock,ip); // //printf("exit client IP:%s......\n",ip); // break; //break while, exit thread // // }else //收到的数据字符串信息,按照十六进制输出 // { // char tempRecvbuf[1024]; // char hexout[1024]; // memcpy(tempRecvbuf,m_cbRecvBuf+m_nRecvSize,nRecvSize); //当前这次收到的数据 // ToHex(tempRecvbuf, nRecvSize, hexout); // //char ip[20]; // get_client_IP(client_sock); // printf("data:\n"); //printf("client IP :%s data:\n",ip); // // printf("recv string:%s ,counter %d byte\n",tempRecvbuf,nRecvSize); // printf("recv 16hex string:%s \n",hexout); // } // // m_nRecvSize += nRecvSize; // 保存已经接收数据的大小 // // while (m_nRecvSize >= sizeof(NetPacketHeader)) // 接收到的数据够不够一个包头的长度 // { // // 读取包头 // NetPacketHeader* pHead = (NetPacketHeader*) (m_cbRecvBuf); // const unsigned short nPacketSize = sizeof(NetPacketHeader)+pHead->frame_datalen; //整个完整一包数据大小,包含包头 // // // 判断是否已接收到足够一个完整包的数据 // if (m_nRecvSize < nPacketSize) // { // // 还不够拼凑出一个完整包 // break; // } // //当收到一个完整包数据信息,打印出来它的客服端ip信息 // //get ip from socket // socklen_t rsa_len = sizeof(struct sockaddr_in); // struct sockaddr_in rsa; // char *ip = NULL; // int port = 0; // if(getpeername(client_sock, (struct sockaddr *)&rsa, &rsa_len) == 0) // { // ip = inet_ntoa(rsa.sin_addr); // port = ntohs(rsa.sin_port); // } // //printf msg from client // printf("from client %s: \n",ip); // // // 拷贝到数据缓存 // memcpy(m_cbDataBuf, m_cbRecvBuf, nPacketSize); // // // 从接收缓存移除 // memmove(m_cbRecvBuf, m_cbRecvBuf+nPacketSize, m_nRecvSize); // m_nRecvSize -= nPacketSize; // // // 解密数据,以下省略 // // ... // // // 分派数据包,让应用层进行逻辑处理 // pHead = (NetPacketHeader*) (m_cbDataBuf); // //printf pHead // printf("net_type:%c,doc_ver:%c,frame_datalen:%d\n",pHead->net_type,pHead->doc_ver,pHead->frame_datalen); // //struct NetPacketHeader //物理链路1Bytes 协议版本1Bytes 帧长2Bytes // // const unsigned short nDataSize = nPacketSize - (unsigned short)sizeof(NetPacketHeader); // OnServiceData(m_cbDataBuf+sizeof(NetPacketHeader), nDataSize); // // // } // end-while // // }//end if FD_ISSET // }//end if-else-select // // }//end for(;;) //
void *doClientThread(void *pParam) { int serverSocket=(int)*(int*)pParam;// int i=(int)*(int*)tid;
doClientRequest(serverSocket); //close(clientSocket); //printf("%d >client socket close ok \n",clientSocket); return NULL; } bool CrcCheckData(const unsigned char* pDataBuffer, unsigned short nDataSize) { //物理链路 1Bytes 协议版本 1Bytes UDP设备识别号(UDID) 6字节 数据包 校验字节 4字节 帧长 2Bytes 业务数据片段 //校验格式: 物理链路 1Bytes 协议版本 1Bytes UDP设备识别号(UDID) 6字节 帧长 2Bytes 密钥 8字节 业务数据片段 数据包 校验字节 CRC32 4字节
unsigned char *p=const_cast<unsigned char*>(pDataBuffer);
// unsigned char data[NET_PACKET_DATA_SIZE]; // unsigned char *pdata=data; // // if(nDataSize >NET_PACKET_DATA_SIZE ) // { // printf("nDataSize >NET_PACKET_DATA_SIZE\n"); // exit(0); // } p=p+8; unsigned int rawCrcresult=0; memcpy(&rawCrcresult,p,4);
// p=p-8;//back to start point
//memcpy(pdata,p,8); //p=p+12; // memcpy(pdata,p,2);//帧长 //p=p+2;//业务数据片段
//unsigned char crypt[8];//密钥 8字节 // memset(crypt,0xaa,8);
//pdata=pdata+10; //memcpy(pdata,crypt,8);
//pdata=pdata+8; //memcpy(pdata,p,nDataSize-14);
//bool res=false; // res=crc32Check( pdata, nDataSize+4, rawCrcresult);
printf("rawCrcresult 4 bytes uint:%d \n",rawCrcresult);
unsigned short int i,k; //jiajianwei rcu c code part unsigned int crc = 0xffffffff; unsigned char* indata = const_cast<unsigned char*>(pDataBuffer); unsigned char g_GprsKey[8]; /*物理链路 + 协议版本 + UDP 设备号 8 bytet*/ //crc = crc32(crc,indata,8); crc = GetBufCRC32( indata, crc, 8 ); /*去掉存储CRC校验码的4个字节*/ //crc = crc32(crc,indata+12,len - 12); // 帧长 crc = GetBufCRC32( indata + 12, crc, 2 ); //密钥 for(i = 0 ;i < 8 ;i ++) { g_GprsKey[i] = 0xaa; } crc = GetBufCRC32( g_GprsKey, crc, 8 ); // 剩下的数据 crc = GetBufCRC32( indata + 14, crc, nDataSize - 14 );
printf("crcCheck 4 bytes uint:%d \n",crc);
bool res=false; if (rawCrcresult == crc ) { res=true; }
return res;
// u32 rawCRCresult=100; // u8 inbuf[50]; // u32 len=50; // crc32Check( p, len, rawCRCresult);
} Timestamp get_timestamp(unsigned char *pdata,int len ) { //9 byte
//12bit time zone //6 bit ms , 20ms unit // 2byte year 1byte m/d/h/m/s
unsigned short timezone; unsigned short ms;
unsigned char *p=pdata; unsigned short head=0; memcpy(&head,p,2);
timezone=head; ms=head;
timezone=timezone>>6; //timzone ms=ms&0x003a; //111111
unsigned short year; unsigned char mon; unsigned char d; unsigned char h; unsigned char m; unsigned char s;
unsigned short umon; unsigned short ud; unsigned short uh; unsigned short um; unsigned short us;
p=p+2; memcpy(&year,p,2); p=p+1; memcpy(&mon,p,1); p=p+1; memcpy(&d,p,1); p=p+1; memcpy(&h,p,1); p=p+1; memcpy(&m,p,1); p=p+1; memcpy(&s,p,1);
umon=mon; ud=d; uh=h; um=m; us=s;
Timestamp tstamp; tstamp.timezone=timezone; tstamp.ms=ms*20; tstamp.year=year; tstamp.month=umon; tstamp.day=ud; tstamp.hour=uh; tstamp.minute=um; tstamp.sencond=us;
return tstamp;
} void * SendtoRCUThread(void *pParam) {
while(1) { usleep(1000); // 1ms while run frequency
bool bget=false;
One_SendPacket sendpacket;
pthread_mutex_lock(&g_mutex_senddata); //Lock(cs); //get one record data from list buffer queue
for (list<One_SendPacket>::iterator it = g_readySendDataList.begin(); it != g_readySendDataList.end(); ++it) { sendpacket=*it; //memcpy(plogin_info,&recvpacket,sizeof(One_RecvdPacket)); bget=true; break;//只取前面第一条 } if(true == bget ) { g_readySendDataList.pop_front(); //从链表头取出一条后,杀掉这条 }
pthread_mutex_unlock(&g_mutex_senddata);
if (false == bget) // if g_readySendDataList size is null , so can't get data { //printf("can't get one record data from g_ReceviedDataList.......\n"); continue;
}else // handle data part {
//char SendData[100];// int nSendsize=0;
char *p=sendpacket.data; sockaddr_in cliaddr; memcpy(&cliaddr,p,sizeof(sockaddr_in)); p=p+sizeof(sockaddr_in); bool rescrc; memcpy(&rescrc,p,sizeof(bool));
p=p+1; NetPacketHeader *pHead=(NetPacketHeader*)p; //memcpy(&Head,p,sizeof(NetPacketHeader)); //defaul respose udp packet ,because longin packet only first connect pHead->frame_datalen=3; //service udp data response
p=p+sizeof(NetPacketHeader); //char Frameindex; //memcpy(&Frameindex,p,1); p=p+1;//char Frameindex; no change char framecontrl1; framecontrl1=0x20;//0010 0000 memcpy(p,&framecontrl1,1); p=p+1;//framecon1 char *framecontrl2=p;
//memcpy(&framecontrl2,p,1); p=p+1;framecon2
p=p+9;//跳过时间戳 char *psevice_total=p; char service_total=0; unsigned short service_ID=0; memcpy(&service_total,p,1); //业务总数1Bytes p=p+1; char *psevice_ID=p; memcpy(&service_ID,p,2); //p=p+2;
//char *ser_len=p; //业务数据长度2Bytes //p=p+2; char *pserviceIDdata=p;//业务ID数据内容
bool isLoginPacket=false;
printf("SendtoRCUThread..service_total:%d,service_ID:%d\n",service_total,service_ID);
if ( (service_total == 1) && (service_ID == 0x0012) )//是登录包 { // D7:1-业务帧,0-响应帧 // D6:1-接收成功 ,0-接收失败 // D5:NC // D4:1-时间戳 ,0-无时间戳 // D3:1-GPS时间(格林尼治时间) ,0-本地时间 // D2:1-校验,0-无校验 // D1-D0 预留 // 响应帧的回传的帧ID和收到的业务帧ID一致。
isLoginPacket=true; printf("is login packet......\n");
*framecontrl2=0x40; //0100 0000 //D7:0-响应帧 D6:1-接收成功 D4:1 0-无时间戳D2:0-无校验
if (rescrc == true) { *framecontrl2= *framecontrl2 & 0xff; //1111 1111 D7 //abc def 10 11 12 13 14 15 }else //fail {
*framecontrl2= *framecontrl2 & 0xbf; //1011 1111 } // *framecontrl2=*framecontrl2 & 0xd0;//1110 0000 D5 // *framecontrl2=*framecontrl2 & 0xf0; //1111 0000 D4 //是登录包-时间戳 // *framecontrl2=*framecontrl2 & 0xf0; //1111 0000 //D3:1-GPS时间(格林尼治时间) ,0-本地时间 // *framecontrl2=*framecontrl2 & 0xf8; //1111 1000 //D2:1-校验,0-无校验 //D1-D0 预留
&nbs