udp server 2013-10-26

本文详细解读了网络数据包的结构与操作码,包括数据包头、数据区域及不同操作码对应的业务流程,旨在深入理解网络通信原理。

 

#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 short  wDataSize; ///< 数据包大小,包含封包头和封包数据大小
// unsigned short  wOpcode; ///< 操作码
//};
//
///// 网络数据包
//struct NetPacket
//{
// NetPacketHeader  Header;       ///< 包头
// unsigned char  Data[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
{
 NetPacketHeader  Header;       ///< 包头
 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
//{
// int  nIndex;
// char arrMessage[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
//   }
//  }
// };
//以下每一条业务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 预留

     /////////////帧序号1BYTES 控制字2BYTES 时间戳9Bytes 业务总数1Bytes 业务ID 2Bytes 业务数据长度2Bytes 业务数据内容
     //char total=1;
     //unsigned short id=0x0012;  //cmd login
                   // memcpy(psevice_total,&total,1);
     //memcpy(psevice_ID,&id,2);

     //unsigned short len=2;
     //memcpy(ser_len,&len,sizeof(unsigned short));
     //char flag[2]={0xaa,0x55};
     //memcpy(pserviceIDdata,flag,2);


     //int templen=2+2+2;   //业务ID 2Bytes 业务数据长度 2Bytes 业务数据内容

     //unsigned int cr = 0xffffffff;
     //unsigned int serviceIDdatacrc = GetBufCRC32( (unsigned char*)psevice_ID, cr,templen  );
     //char * tempp=psevice_ID;
     //tempp=tempp+templen;
     //memcpy(tempp,&serviceIDdatacrc,4);  //校验字4Bytes
     //业务ID 2Bytes 业务数据长度  2Bytes 业务数据内容 业务ID 2Bytes 业务数据长度 2Bytes 业务数据内容 …… 校验字4Bytes

     ///////////////get UDID from dev serial  SN///////////////////////////////////////////////////////////

     //帧序号 1BYTES 控制字 2BYTES 时间戳 9Bytes 业务总数 1Bytes 业务ID 2Bytes 业务数据长度 2Bytes 业务数据内容

     //得到SN,用十六进制保存到6字节UDID ,memcpy
     //设备类型 设备硬件版本号 设备软件版本号 车型语言 车型名称 车型版本 运营商名称 设备序列号 设备IMEI码 SIM卡号 加密文本
     // DPU String DPU String DPU String DPU String DPU String DPU String    12Bytes    12Bytes     15Bytes    20Bytes 32Bytes


     char *myp=pserviceIDdata+2;
     unsigned short datalen=0;
     memcpy(&datalen,myp,2);
     
     int startlen=datalen-12-15-20-32;
     char * pdevserial=pserviceIDdata+startlen;  //

     char chSN[12];
     memcpy(chSN,pdevserial,12);

     long long llSN=0;
     sscanf(chSN, "%lld", &llSN);
     char chstrSN[20];
     memcpy(chstrSN,chSN,12);
     printf("device serial string:%s\n",chstrSN);
     printf("device serial SN long long value:%lld\n",llSN);
     char hex[20];
     char chUUID[6];
     sprintf(hex, "%llx", llSN);
     if ((strlen(hex)%2) != 0) //奇数个,十六进制串前补个0
     {
      char temp[20];
      memcpy(temp,hex,20);
      hex[0]=0;
      memcpy(hex+1,temp,20-1);
     }
     unsigned int v;
     int L=strlen(hex); //此时这里肯定是偶数个
     int i;
     for (i=0;i<L/2;i++) {
      sscanf(hex+i*2,"%2X",&v);
      chUUID[i+6-L/2]=(char)(v&0xFFu);  //这里UUID6字节如0xe1e2e3 为 0x000000e1e2e3
     }
     memcpy(pHead->UDID,chUUID,6);   //memcpy llsn(hex) to UDID part  类似 0x000000e1e2e3  生成UDID

     //以后获取SN
     // long long lval;
     //sscanf("0x000000a1a2ae", "%llx", &lval);

    }else  //framecontrl2 modify //响应业务数据帧
    {
     *framecontrl2= 0x44;             //0100 0100
     if (rescrc == true)
     {
      *framecontrl2= *framecontrl2 & 0xff;   //1111 1111  D7  //abcdef  10 11 12 13 14 15
     }else //fail
     {

      *framecontrl2= *framecontrl2 & 0xbf;   //1011 1111
     }
     //      }
//      *framecontrl2=0xff;
//
//      *framecontrl2= *framecontrl2 & 0x00;   //0000 0000  D7  D7:1-业务帧,0-响应帧
//      if (rescrc == true)
//      {
//       *framecontrl2= *framecontrl2 & 0xc0;   //1100 0000  D7  //abcdef  10 11 12 13 14 15
//      }else //fail
//      {
//
//       *framecontrl2= *framecontrl2 & 0x80;   //1000 0000
//      }
//      *framecontrl2=*framecontrl2 & 0xd0;//1110 0000  D5
//      *framecontrl2=*framecontrl2 & 0xe0;     //1110 0000  D4 //响应-无时间戳
//      *framecontrl2=*framecontrl2 & 0xf0;     //1111 0000     //D3:1-GPS时间(格林尼治时间) ,0-本地时间
//      *framecontrl2=*framecontrl2 & 0xf8;     //1111 1000 //D2:1-校验,0-无校验
//      //D1-D0 预留

    
    }// if ( (service_total == 1) && (service_ID == 0x0012) )//是登录包
    
               
    //时间戳9Bytes 业务总数1Bytes 业务ID 2Bytes ---复制这部分类判断是否登录包--service-total==1&& serverID=0012
    ///////////判断是否登录包///////////////////////////////////////////////////////////////

    //0010(网管服务器发送)0x20
    //////////////////////////////////////////////////////////////////////////


       socklen_t clilen;
       clilen=sizeof(cliaddr);
    //crc check data part..........

        char *temp=sendpacket.data+sizeof(sockaddr_in)+sizeof(rescrc);
        unsigned char *pDataBuffer=(unsigned char *)temp;
     unsigned short i;   //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 );
     // 剩下的业务数据
     if(isLoginPacket)  //登录
     {

      //int templen=3; 
      pHead->frame_datalen=1+2;////帧序号 1BYTES 控制字 2BYTES

      //crc = GetBufCRC32( indata + 14, crc,pHead->frame_datalen );  //帧序号 1BYTES 控制字 2BYTES 

      int crclen=sizeof(NetPacketHeader) + pHead->frame_datalen;
      unsigned int crcresult=gprs_data_crc32( indata,crclen );
      printf("jiajianwei:sendpacket crcCheck  4 bytes uint:%d \n",crcresult);//crc
      //printf("sendpacket crcCheck  4 bytes uint:%d \n",crc);//crc

      memcpy(indata+8,&crcresult,4);//copy crc 4bytes result

      {
       //十六进制打印发送答应包
          //char tempRecvbuf[1024];
          char hexout[1024];
          printf("send 16hex string: \n");
          for (int k=0;k<sizeof(NetPacketHeader)+pHead->frame_datalen;k++)
          {
                                          printf("%x ",indata[k]);
          }
          //ToHex((char*)indata, sizeof(NetPacketHeader)+pHead->frame_datalen, 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("send 16hex string:%s \n",hexout);  
      }

      //char *pdata=sendpacket.data+sizeof(sockaddr_in)+sizeof(rescrc);
      nSendsize=sizeof(NetPacketHeader)+pHead->frame_datalen; //login send
      sendto(g_server_sock, indata, nSendsize, 0, (struct sockaddr *)&cliaddr, clilen);  //登录响应

      //memcpy(p,pDataBuffer,14+1+2);
      char *tempip=NULL;
      printf("s_addr:%d\n",cliaddr.sin_addr.s_addr);
      tempip = inet_ntoa(cliaddr.sin_addr);
      int port = ntohs(cliaddr.sin_port);
      printf("login response send to ip:%s:%d,len:%d\n",tempip,port,nSendsize);

     }else
     {

      //crc = GetBufCRC32( indata + 14, crc, 3 );  //帧序号 1BYTES 控制字 2BYTES 
      int crclen=sizeof(NetPacketHeader) + 1+2;
      unsigned int crcresult=gprs_data_crc32( indata,crclen );
      printf("jiajianwei:sendpacket crcCheck  4 bytes uint:%d \n",crcresult);//crc
      //printf("sendpacket crcCheck  4 bytes uint:%d \n",crcresult);
      memcpy(indata+8,&crcresult,4);//copy crc 4bytes result       
      //char *pdata=sendpacket.data+sizeof(sockaddr_in)+sizeof(rescrc);
      nSendsize=sizeof(NetPacketHeader)+1+2; //响应发送
      sendto(g_server_sock, indata, nSendsize, 0, (struct sockaddr *)&cliaddr, clilen);

      //memcpy(p,pDataBuffer,14+1+2);
      char *tempip=NULL;  //get udp client ip info
      printf("s_addr:%d\n",cliaddr.sin_addr.s_addr);
      tempip = inet_ntoa(cliaddr.sin_addr);
      int port = ntohs(cliaddr.sin_port);
      printf("service response send to ip:%s:%d,len:%d\n",tempip,port,nSendsize);
     }
    


    //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

   }
 }//end-while


}

uint32_t gprs_data_crc32(uint8_t * indata,uint16_t len)
{
 uint16_t i,k;
 uint32_t crc = 0xffffffff;
 /*物理链路 + 协议版本 + 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 );
 //密钥
 unsigned char g_GprsKey[8];

 for(i = 0 ;i < 8 ;i ++)
 {
  g_GprsKey[i] = 0xaa;
 }
 crc = GetBufCRC32( g_GprsKey, crc, 8 );
 // 剩下的数据
 crc = GetBufCRC32( indata + 14, crc, len - 14 );
}

void  SendtoRCU_packet(sockaddr_in  cliaddrIP ,const unsigned char* pDataBuffer, unsigned short nDataSize,bool crcresult) //pDataBuffer packethead+帧序号1BYTES+ 控制字2BYTES
{

    //crc result  D6:1-接收成功 ,0-接收失败
//  帧控制字2 Frame_Contrl_2 1 D7:1-业务帧,0-响应帧
// D6:1-接收成功 ,0-接收失败
// D5:NC
// D4:1-时间戳 ,0-无时间戳
// D3:1-GPS时间(格林尼治时间) ,0-本地时间
// D2:1-校验,0-无校验
//    D1-D0 预留
//    响应帧的回传的帧ID和收到的业务帧ID一致。

 

}
void  OnServiceData(sockaddr_in  cliaddrIP ,const unsigned char* pDataBuffer, unsigned short nDataSize )        //整个udp一包数据
{
  //add code , 根据业务ID数,先解析数据到每个业务数据下
  //帧序号1BYTES 控制字2BYTES 时间戳9Bytes 业务总数1Bytes 业务ID 2Bytes 业务数据长度2Bytes 业务数据内容 业务ID 2Bytes
          bool res=false;
       res=CrcCheckData(pDataBuffer,nDataSize);

    ///////////insert one sendpacket to list for sendtothread///////////////////////////////////////////////////////////////
     One_SendPacket sendpacket;
              char *psend=sendpacket.data;
     sockaddr_in  cliaddr= cliaddrIP;
              memcpy(psend,&cliaddr,sizeof(sockaddr_in));
     psend=psend+sizeof(sockaddr_in);
     memcpy(psend,&res,sizeof(bool));
     psend=psend+1;
     memcpy(psend,pDataBuffer,nDataSize);  //14+1+2+9+1+2);  //时间戳9Bytes 业务总数1Bytes 业务ID 2Bytes ---复制这部分类判断是否登录包--service-total==1&& serverID=0012

     //memcpy(sendpacket.data, mesg, nRecvsize);

     pthread_mutex_lock(&g_mutex_senddata); //Lock(cs); //插入数据到包队列里

        g_readySendDataList.push_back(sendpacket);
        printf("insert one send packet to list.....\n");

     pthread_mutex_unlock(&g_mutex_senddata); //Lock(cs);
    //////////////////////////////////////////////////////////////////////////
   

    if (false == res )
    {
     printf("crc32 check data packet error,don't handle,throw it ....\n");
     return;

    }else
    {
              printf("crc32 check data packet success ....\n");
    }

   // SendtoRCU_packet(sockaddr_in  cliaddrIP ,const unsigned char* pDataBuffer, unsigned short nDataSize,bool crcresult);

       unsigned char *p=const_cast<unsigned char*>(pDataBuffer);  //char *p=pDataBuffer;//指向整数据帧的开头
          NetPacketHeader* pHead = (NetPacketHeader*)(p);
    unsigned char    frame_index=0;
    unsigned short   frame_control=0;
    //timestamp 9 bytes
    unsigned char    service_totalnum=0;
 
    printf("net_type:%c,doc_ver:%c,UDID:%s,frame_datalen:%d\n",pHead->net_type,pHead->doc_ver,pHead->UDID,pHead->frame_datalen);

    if(  nDataSize != (pHead->frame_datalen+14) ) //check packet real length
    {
                printf("pHead->frame_datalen problems ,it is not equal the recv udp one packet length -14... \n");
    printf("udp one packet nDataSize:%d,pHead->frame_datalen:%d,sizeof(NetPacketHeader):%d...\n",nDataSize,pHead->frame_datalen,sizeof(NetPacketHeader) );
    }
   
    long long myudid;
    char chudid[10];
    memcpy(chudid,pHead->UDID,6);
    sscanf(chudid, "%llx", &myudid);  //从类似0x000000e1e2e2 转 longlong

    p=p+sizeof(NetPacketHeader); //指向业务数据开头

    memcpy(&frame_index,p,sizeof(frame_index));
 
    p=p+sizeof(frame_index);
    memcpy(&frame_control,p,sizeof(frame_control));
 
    p=p+sizeof(frame_control);
     //timestamp
    unsigned char chstamp[9];

    Timestamp stamp=get_timestamp(chstamp,9);
    printf("udp packet timestamp:%d,%d,%d,%d,%d,%d,%d,%d...\n",stamp.timezone,stamp.ms,stamp.year,stamp.month,stamp.day,stamp.hour,stamp.minute,stamp.sencond);
    p=p+9;//解析timestamp
    memcpy(&service_totalnum,p,sizeof(service_totalnum));
 
    p=p+sizeof(service_totalnum);
 
    printf("frame_index:%d,frame_control:%d\n",frame_index,frame_control);
    printf("service totalnum: %d\n",service_totalnum);
 
    int i=0;
    for(i=0;i<service_totalnum;i++)   //整个一包业务数据(包含所有业务)的解码,解完整包作为一条RCU信息记录入数据库
    {
     //业务ID 2Bytes 业务数据长度 2Bytes 业务数据内容

        unsigned short service_ID=0;
      unsigned short ID_datalen=0;   
      memcpy(&service_ID,p,sizeof(service_ID));  //service_ID=TwoByte2short(p);
        //memcpy(&service_ID,id,sizeof(service_ID));//service_ID=*(unsigned short*)p;
        p=p+sizeof(service_ID);
        memcpy(&ID_datalen,p,sizeof(ID_datalen));
        p=p+sizeof(ID_datalen);
       
        printf( "sevice_ID:%d,ID_datalen:%d\n",service_ID,ID_datalen );
       
        OnServiceIDMessage(myudid,service_ID,p,ID_datalen);//一条业务ID数据
       
        p=p+ID_datalen;////下一条业务ID数据
   
    }
        
   
      //OnServiceIDMessage(pHead->wOpcode, m_cbDataBuf+sizeof(NetPacketHeader), nDataSize);//每个业务ID下的数据解包
}

bool OnServiceIDMessage( long long udid,const unsigned short nOpcode,const unsigned char* pDataBuffer, unsigned short nDataSize )
//bool OnServiceIDMessage( const unsigned short nOpcode,const unsigned char* pDataBuffer, unsigned short nDataSize ) //service ID根据业务命令,解析收到的一包有效数据
{
 switch (nOpcode)
 {
 case NET_TEST1:
  {
   //NetPacket_Test1* pMsg = (NetPacket_Test1*) pDataBuffer;
   //return OnNetPacket(pMsg);
  }
  break;

 case CMD_NET_LOGIN:    //0x0012    18
  {
//    NetPacket_Test1* pMsg = (NetPacket_Test1*) pDataBuffer;
//    return OnNetPacket(pMsg);

   //解析数据设备类型:(ASC II 码)。设备硬件版本号:(ASC II 码)。设备软件版本号:(ASC II 码)。车型语言:(ASC II 码)。车型名称:(ASC II 码)。车型版本:

   printf("CMD_NET_LOGIN\n");

   //pDataBuffer, unsigned short nDataSize data 指针与长度

   unsigned char *p=(unsigned char*)pDataBuffer;
   Struct_Login_Info login_info;
   memset(&login_info,0,sizeof(Struct_Login_Info));

   memcpy(&login_info.Device_type.uLen,p,sizeof(login_info.Device_type.uLen)); //login_info.Device_type.uLen=TwoByte2short(p);//
   p=p+sizeof(login_info.Device_type.uLen);
            memcpy(login_info.Device_type.data,p,login_info.Device_type.uLen);
            p=p+login_info.Device_type.uLen;

   memcpy(&login_info.Hardware_ver.uLen,p,sizeof(login_info.Hardware_ver.uLen));//login_info.Hardware_ver.uLen=TwoByte2short(p);//
   p=p+sizeof(login_info.Hardware_ver.uLen);
   memcpy(login_info.Hardware_ver.data,p,login_info.Hardware_ver.uLen);
   p=p+login_info.Hardware_ver.uLen;

   memcpy(&login_info.Software_ver.uLen,p,sizeof(login_info.Software_ver.uLen));//login_info.Software_ver.uLen=TwoByte2short(p);//
   p=p+sizeof(login_info.Software_ver.uLen);
   memcpy(login_info.Software_ver.data,p,login_info.Software_ver.uLen);
   p=p+login_info.Software_ver.uLen;

   memcpy(&login_info.Car_language.uLen,p,sizeof(login_info.Car_language.uLen));//login_info.Car_language.uLen=TwoByte2short(p);//
   p=p+sizeof(login_info.Car_language.uLen);
   memcpy(login_info.Car_language.data,p,login_info.Car_language.uLen);
   p=p+login_info.Car_language.uLen;

   memcpy(&login_info.Car_name.uLen,p,sizeof(login_info.Car_name.uLen));//login_info.Car_name.uLen=TwoByte2short(p);//
   p=p+sizeof(login_info.Car_name.uLen);
   memcpy(login_info.Car_name.data,p,login_info.Car_name.uLen);
   p=p+login_info.Car_name.uLen;
   
   memcpy(&login_info.Car_ver.uLen,p,sizeof(login_info.Car_ver.uLen));//login_info.Car_ver.uLen=TwoByte2short(p);//
   p=p+sizeof(login_info.Car_ver.uLen);
   memcpy(login_info.Car_ver.data,p,login_info.Car_ver.uLen);
   p=p+login_info.Car_ver.uLen;


   
   memcpy(login_info.Vendor_name,p,sizeof(login_info.Vendor_name));
   p=p+sizeof(login_info.Vendor_name);

   memcpy(login_info.Device_serial,p,sizeof(login_info.Device_serial));
   p=p+sizeof(login_info.Device_serial);

   memcpy(login_info.Device_IMEI,p,sizeof(login_info.Device_IMEI));
   p=p+sizeof(login_info.Device_IMEI);

   memcpy(login_info.SIM_num,p,sizeof(login_info.SIM_num));
   p=p+sizeof(login_info.SIM_num);

   memcpy(login_info.Crypt_txt,p,sizeof(login_info.Crypt_txt));
   
   //printf("size:%d,%d,%d,%d\n",sizeof(login_info.Vendor_name),sizeof(login_info.Device_serial),sizeof(login_info.Device_IMEI),sizeof(login_info.SIM_num));
   //p=p+sizeof(login_info.Crypt_txt);
     
   printf("ulen:device_type:%d,hardware_ver:%d,software_ver:%d,car_language:%d,car_name%d,car_ver:%d\n",\
   login_info.Device_type.uLen,login_info.Hardware_ver.uLen,login_info.Software_ver.uLen,login_info.Car_language.uLen,login_info.Car_name.uLen,\
   login_info.Car_ver.uLen);
   //check data len valid
   const int valid_len=32;
   if (login_info.Device_type.uLen > valid_len || login_info.Hardware_ver.uLen >valid_len || login_info.Software_ver.uLen > valid_len || \
    login_info.Car_language.uLen> valid_len || login_info.Car_name.uLen>valid_len || login_info.Car_ver.uLen > valid_len )
   {
    printf("check login info data len error,big valid_len...\n");
    exit(0);
   }
          
//   printf("device_type:%s,hardware_ver:%s,software_ver:%s,car_language:%s,car_name:%s,car_ver:%s,vendor_name:%s,Device_serial:%s,Device_IMEI:%s,SIM_num:%s,crypt_txt:%s\n", \
//    login_info.Device_type.data,login_info.Hardware_ver.data,login_info.Software_ver.data,login_info.Car_language.data,login_info.Car_name.data,login_info.Car_ver.data,\
//    login_info.Vendor_name,login_info.Device_serial,login_info.Device_IMEI,login_info.SIM_num,login_info.Crypt_txt);
   printf("device_type:%s,hardware_ver:%s,software_ver:%s,car_language:%s,car_name:%s,car_ver:%s\n", \
    login_info.Device_type.data,login_info.Hardware_ver.data,login_info.Software_ver.data,login_info.Car_language.data,login_info.Car_name.data,login_info.Car_ver.data);
   
   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,login_info.Vendor_name,sizeof(login_info.Vendor_name));
   memcpy(Device_serial,login_info.Device_serial,sizeof(login_info.Device_serial));
   memcpy(Device_IMEI,login_info.Device_IMEI,sizeof(login_info.Device_IMEI));
   memcpy(SIM_num,login_info.SIM_num,sizeof(login_info.SIM_num));
   memcpy(Crypt_txt,login_info.Crypt_txt,sizeof(login_info.Crypt_txt));
           
   printf("vendor_name:%s,Device_serial:%s,Device_IMEI:%s,SIM_num:%s,crypt_txt:%s\n",Vendor_name,Device_serial,Device_IMEI,SIM_num,Crypt_txt);

   //////////////////one sql ////////////////////////////////////////////////////////

//    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));

   One_InsertSql  onesql;
   
   Struct_Login_Info lf=login_info;
   sprintf(onesql.data,"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(onesql.data),onesql.data);
   
   put_record(onesql);
   //put_record(login_info);   ////暂时把登陆信息当作整包业务数据记录,之后是指写入数据库的一条记录,来自设备的整包业务数据

   //物理链路1Bytes 协议版本  1Bytes UDP设备识别号(UDID) 6字节 数据包 校验字节4字节 帧长2Bytes 业务数据片段

 

   //sendto(g_server_sock, mesg, n, 0, pcliaddr, len);
  }
  break;
  
  case CMD_NET_GPS_DATA:           // = 0x0022,//2.3.8 终端定位数据-0X0022
  {
   
   
   printf("CMD_NET_GPS_DATA\n");

   //pDataBuffer, unsigned short nDataSize data 指针与长度

   unsigned char *p=(unsigned char*)pDataBuffer;
   

   char GPS_way;
   memcpy(&GPS_way,p,1);
   p=p+1;  //<定位数据>
   //   业务数据内容描述如下:
   //<定位方式> + <定位数据>
   //定位方式:1 字节,0x01 = GPS标准定位,0x02 = GPS精简定位,0x05 = 基站定位。

   //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 数据)。
   // HDOP,水平精度因子,范围0.5~99.9,数字越大表明误差越大,99.9 表明未定位(GPGGA 数据)。
   // 海拔高度,单位为米,范围为-9999.9~99999.9,(GPGGA 数据)。
   // 定位模式1 字节,1 = 未定位, 2 = 二维定位, 3 = 三维定位。(GPGSA 数据)
   // 有效卫星个数,可见讯号的卫星的总数,00 至 12(GPGSV 数据)。
   //基站定位信息数据长度不定,格式为:
       //<date>,<time>,<lat>,<long>,<alt>,<uncertainty>// 这个数据顺序是定死了的
       //01/02/2013,11:22:00.100,10.0,11.0,14.0,100  //根据','来解析不同数据
   //        GPS_STRDAND     =0x01,
   // GPS_SIMPLE      =0x02,
   // GPS_BASE        =0x05,
      int Pos_data_len=nDataSize-1;


   if (GPS_way == GPS_STRDAND)
   {
    GPS_DataStandard  gps_data;
    printf("GPS_way == GPS_STRDAND...\n");
          //char tempdata[256];
    //memcpy(tempdata,p,nDataSize-1);

    int gps_datalen[30];
    unsigned char *gprs_straddr[30];
    //unsigned char s[200]="45454545454545,4,,1,2,3,44646";
    unsigned char *s=p;
    int  num= Find_char_add_len(p,gps_datalen,gprs_straddr);
    printf("num:%d\n",num);
    for (int n=0;n<gps_datalen[0]-1;n++)  //第一数据 UTC_time
    {
     printf("%c",s[n]);
    }
    //
//     memcpy(gps_data.UTC_time,s,6);//hms
//           int ms=0;
//     int len=gps_datalen[0]-1;
//     unsigned char *ch=NULL;
//     ch=s+6+1;
//     memcpy(&ms,ch,len-7); //ms
//     gps_data.UTC_time[3]=ms;
//     if (7==i) 
//     {
//      if (gps_datalen[i+1]-1)
//      {
      //float   weidu[2];/
      char ch[10];
      memset(ch,0,10);
      int leng=gps_datalen[0]-1;
      memcpy(ch,s,2);
      gps_data.UTC_time[0]=atoi(ch);
      memcpy(ch,s+2,2);
      gps_data.UTC_time[1]=atoi(ch);
      memcpy(ch,s+4,2);
      gps_data.UTC_time[2]=atoi(ch);
      memcpy(ch,s+6,leng-6);
      gps_data.UTC_time[3]=atoi(ch);


//      }
//
//     }

    printf("\n");
    int prt = 0;
    for (int i=0;i<num ;i++) //gps param resolv
    {
     printf("index :%d ",i);
     prt = 1;
     for (int k=0;k<gps_datalen[i+1]-1;k++)
     {
      printf("%c",*(gprs_straddr[i]+prt));
      prt ++;
     }
     if (0==i)  //定位有效性
     {
                  if (gps_datalen[i+1]-1)
                  {
       memcpy(&gps_data.posvalid,gprs_straddr[i]+1,1);
                  }
                  
     
     }
     if (1==i)  //纬度
     {
      if (gps_datalen[i+1]-1)
      {
       //float   weidu[2];/
       char ch[10];
       memset(ch,0,10);
       memcpy(ch,gprs_straddr[i]+1,2);
       gps_data.weidu[0]=atoi(ch);
                      int leng=gps_datalen[i+1]-1;
                      memcpy(ch,gprs_straddr[i]+1+2,leng-2);                  
       gps_data.weidu[1]=atoi(ch);
      
      }

     }
     if (2==i)  //// 北纬或南纬
     {
      if (gps_datalen[i+1]-1)
      {
                  memcpy(&gps_data.beiwei,gprs_straddr[i]+1,1);

      }

     }
     //经度
     if (3==i) 
     {
      if (gps_datalen[i+1]-1)
      {
       //float   weidu[2];/
       char ch[10];
       memset(ch,0,10);
       memcpy(ch,gprs_straddr[i]+1,3);
       gps_data.jingdu[0]=atoi(ch);
       int leng=gps_datalen[i+1]-1;
       memcpy(ch,gprs_straddr[i]+1+3,leng-3);                  
       gps_data.jingdu[1]=atoi(ch);

      }

     }    
     //东经或西经
     if (4==i)  ////
     {
      if (gps_datalen[i+1]-1)
      {
       memcpy(&gps_data.dongjing,gprs_straddr[i]+1,1);

      }

     }
     //速度
     if (5==i) 
     {
      if (gps_datalen[i+1]-1)
      {
       //float   weidu[2];/
       char ch[10];
       memset(ch,0,10);
       int leng=gps_datalen[i+1]-1;
       memcpy(ch,gprs_straddr[i]+1,leng);

       gps_data.speed=atof(ch);

      }

     }
              //方位角
     if (6==i) 
     {
      if (gps_datalen[i+1]-1)
      {
       //float   weidu[2];/
       char ch[10];
       memset(ch,0,10);
       int leng=gps_datalen[i+1]-1;
       memcpy(ch,gprs_straddr[i]+1,leng);

       gps_data.direction_angle=atof(ch);

      }

     }
     //UTC 日期dmmyy(日月年)

     if (7==i) 
     {
      if (gps_datalen[i+1]-1)
      {
       //float   weidu[2];/
       char ch[10];
       memset(ch,0,10);
       int leng=gps_datalen[i+1]-1;
       memcpy(ch,gprs_straddr[i]+1,2);
       gps_data.UTC_date[0]=atoi(ch);
       memcpy(ch,gprs_straddr[i]+1+2,2);
       gps_data.UTC_date[1]=atoi(ch);
       memcpy(ch,gprs_straddr[i]+1+4,2);
       gps_data.UTC_date[2]=atoi(ch);


      }

     }

              //GPS 状态
     if (8==i)  //// 北纬或南纬
     {
      if (gps_datalen[i+1]-1)
      {
       memcpy(&gps_data.GPS_status,gprs_straddr[i]+1,1);

      }

     }
               //HDOP
     if (9==i) 
     {
      if (gps_datalen[i+1]-1)
      {
       //float   weidu[2];/
       char ch[10];
       memset(ch,0,10);
       int leng=gps_datalen[i+1]-1;
       memcpy(ch,gprs_straddr[i]+1,leng);

       gps_data.HDOP=atof(ch);

      }

     }
     //海拔高度
     if (10==i) 
     {
      if (gps_datalen[i+1]-1)
      {
       //float   weidu[2];/
       char ch[10];
       memset(ch,0,10);
       int leng=gps_datalen[i+1]-1;
       memcpy(ch,gprs_straddr[i]+1,leng);

       gps_data.high=atof(ch);

      }

     }

     if (11==i)  //// <定位模式> ,
     {
      if (gps_datalen[i+1]-1)
      {
       memcpy(&gps_data.posmodel,gprs_straddr[i]+1,1);

      }

     }
     //<有效卫星个数>

     if (12==i) 
     {
      if (gps_datalen[i+1]-1)
      {
       //float   weidu[2];/
       char ch[10];
       memset(ch,0,10);
       int leng=gps_datalen[i+1]-1;
       memcpy(ch,gprs_straddr[i]+1,2);
  
       gps_data.star_num=atoi(ch);


      }

     }

     //////////////////////////////////////////////////////////////////////////
        //printf("...len:%d",gps_datalen[i+1]-1);
     printf("\n ");

    }//for (int i=0;i<num ;i++) //gps param resolv


          GPS_DataStandard gps=gps_data;

    printf("utc_time:hms%d,%d,%d,%d;posvalid:%c;weidu:%f,%f;beiwei:%c;jingdu:%f,%f;dongjing:%c;speed:%f;direction angle:%f;UTC_date:%d,%d,%d;gps_status:%c; \
     hdop:%f;high:%f;posmodel:%c;starnum:%d;\n",gps.UTC_time[0],gps.UTC_time[1],gps.UTC_time[2],gps.UTC_time[3],gps.posvalid,gps.weidu[0],gps.weidu[1], \
     gps.beiwei,gps.jingdu[0],gps.jingdu[1],gps.dongjing,gps.speed,gps.direction_angle,gps.UTC_date[0],gps.UTC_date[1],gps.UTC_date[2],gps.GPS_status,\
     gps.HDOP,gps.high,gps.posmodel,gps.star_num);

    One_InsertSql  onesql;
 
          long long myUDID=987654321012;
    sprintf(onesql.data,"insert into GPSdatastandard (UDID,utc_time_h,utc_time_m,utc_time_s,utc_time_ms,posvalid,weidu_d,weidu_f,beiwei,jingdu_d,jingdu_f,dongjing,speed, \
         direction_angle,utc_date_d,utc_date_m,utc_date_y,GPS_status,HDOP,high, posmodel, star_num) \
         values ('%lld','%d','%d','%d','%d','%c','%f','%f','%c','%f','%f','%c','%f','%f','%d','%d','%d','%c','%f','%f','%c','%d')",\
        myUDID,gps.UTC_time[0],gps.UTC_time[1],gps.UTC_time[2],gps.UTC_time[3],gps.posvalid,gps.weidu[0],gps.weidu[1], \
         gps.beiwei,gps.jingdu[0],gps.jingdu[1],gps.dongjing,gps.speed,gps.direction_angle,gps.UTC_date[0],gps.UTC_date[1],gps.UTC_date[2],gps.GPS_status,\
         gps.HDOP,gps.high,gps.posmodel,gps.star_num);
    printf("chsql:%d,%s\n",strlen(onesql.data),onesql.data);

    put_record(onesql);
   
    //char buf[14][20];  //14 is parameter nums
    //char buf1[20];char buf2[20];char buf3[20];char buf4[20];char buf5[20];char buf6[20];char buf7[20];
    //char buf8[20];char buf9[20];char buf10[20];char buf11[20];char buf12[20];char buf13[20];char buf14[20];

    //sscanf("1,2,3,4,5,6,7,8,9,10,11,12,13,14 ", "%1s,%1s,%1s,%1s,%1s,%1s,%1s,%1s,%1s,%2s,%2s,%2s,%2s,%2s", buf1,buf2,buf3,buf4,buf5,buf6,buf7,buf8,buf9,buf10,buf11,buf12,buf13,buf14);
    //sscanf(tempdata, "%1s,%1s,%1s,%1s,%1s,%1s,%1s,%1s,%1s,%2s,%2s,%2s,%2s,%2s", \
   //  buf1,buf2,buf3,buf4,buf5,buf6,buf7,buf8,buf9,buf10,buf11,buf12,buf13,buf14);
//     int i=0;
//     int signpos_last=0;
//     int signpos_cur=0;
//     unsigned char *ps=p;
//     int param_index=0;

     //for(i=0;i<Pos_data_len;i++)
     //{
     // if(p[i] == ',')
     // {
     //  signpos_cur=i-1;
     //  if (i == 0) //'0'
     //  {
     //                     signpos_cur=0;
     //  }
     //  param_index++;

     //  ps=p+signpos_last;

     //  if ()
     //  {
     //  }else
     //  {
     //     memcpy(buf[param_index],ps,signpos_cur-signpos_last+1);
     //  }
     //     
     //  signpos_last=i+1;         
     // }//end-if (p[i] == ',')


     //}  


   }  //if (GPS_way == GPS_STRDAND)


      if(GPS_way == GPS_BASE)
       {
        int i=0;
            int signpos_last=0;
            int signpos_cur=0;
      
//           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;
            int param_index=0;
            GPS_DataBase  GPS_db;
            unsigned char *ps=p;
      for(i=0;i<Pos_data_len;i++)
        {
           if(p[i] == ',')
            {
             signpos_cur=i-1;
             
             param_index++;
             if(param_index == 1)
              {
               ps=p+signpos_last;
               memcpy(GPS_db.date,ps,signpos_cur-signpos_last+1);
              }
             if(param_index == 2)
              {
               ps=p+signpos_last;
               memcpy(GPS_db.time,ps,signpos_cur-signpos_last+1);
              } 
             if(param_index == 3)
              {
               ps=p+signpos_last;
               memcpy(GPS_db.lat_info,ps,signpos_cur-signpos_last+1);
              }            
             if(param_index == 4)
              {
               ps=p+signpos_last;
               memcpy(GPS_db.long_info,ps,signpos_cur-signpos_last+1);
              }               
             if(param_index == 5)
              {
               ps=p+signpos_last;
               char temp[20];
               memcpy(temp,ps,signpos_cur-signpos_last+1);
               sscanf(temp,"%d",&GPS_db.alt_info);
              }               
             if(param_index == 6)
              {
               ps=p+signpos_last;
               char temp[20];
               memcpy(temp,ps,signpos_cur-signpos_last+1);
               sscanf(temp,"%d",&GPS_db.uncertainty);
               
              }      
              
              signpos_last=i+1;         
            }//end-if (p[i] == ',')
   
         
        }  
       
     }//end-if GPS_BASE
 
   //Struct_Login_Info login_info;
   //memset(&login_info,0,sizeof(Struct_Login_Info));
   
   
  }
  break;
  
  case CMD_NET_DIAGNOSIS_DATA:          // = 0x0030,       //诊断数据
  {
   
   
   
   //NetPacket_Test1* pMsg = (NetPacket_Test1*) pDataBuffer;
   //return OnNetPacket(pMsg);
   
   
  }
  break;
 

 default:
  {
   //printf("unkonw service ID:%d and data...\n",nOpcode);   //std::cout << "收取到未知网络数据包:" << nOpcode << std::endl;
   return false;
  }
  break;
 }
}


void ToHex(  char * src, int length, char * dst ) //char array to 16hex output
{
    char temp[3];
    int i=0;
    for ( i = 0; i < length; ++i)
    {
      char result[3] = {'0', '0', ' '};
        //itoa(src[i], temp, 16);
        sprintf(temp,"%x",src[i]);
        if (strlen(temp) == 1)
            memcpy(result + 1, temp, 1);
        else
            memcpy(result, temp, 2);
  
        memcpy(dst + 3 * i, result, 3);
    }
 
}
void get_client_IP(int clientsock)
{

      socklen_t rsa_len = sizeof(struct sockaddr_in);
     struct sockaddr_in rsa;
     char *temip = NULL;
     int port = 0;
    if(getpeername(clientsock, (struct sockaddr *)&rsa, &rsa_len) == 0)
    {
            temip = inet_ntoa(rsa.sin_addr);
            port = ntohs(rsa.sin_port);
    }
    //int len=strlen(temip);
    //printf("ip len:%d\n",len);
    //sprintf(ip,"%s",temip);  //memcpy(ip,temip,20);
    
    printf("client IP:%s :\n",temip);
 
}
//void get_client_IP(int clientsock,char *ip)
//{
//
//      socklen_t rsa_len = sizeof(struct sockaddr_in);
//     struct sockaddr_in rsa;
//     char *temip = NULL;
//     int port = 0;
//    if(getpeername(clientsock, (struct sockaddr *)&rsa, &rsa_len) == 0)
//    {
//            temip = inet_ntoa(rsa.sin_addr);
//            port = ntohs(rsa.sin_port);
//    }
//    int len=strlen(temip);
//    printf("ip len:%d\n",len);
//    sprintf(ip,"%s",temip);  //memcpy(ip,temip,20);
//    
//    //printf("from client IP:%s\n",ip);
// 
//}
unsigned short TwoByte2short(char *p)
{
      unsigned short res=0;
      char id[2];
       memcpy(id+1,p,1);
       memcpy(id,p+1,1);//char[]转unsigned short swap low/high byte
       memcpy(&res,id,sizeof(unsigned short));
      return res;
}
unsigned char Find_char_add_len(unsigned char *indata,int *gps_datalen,unsigned char *gprs_straddr[])
{
 int  dlen,dotnum;

 dotnum = 0;
 dlen = 0;
 //memset(gps_datalen,0,20);
 while(indata != '\0')
 {
  dlen ++;
  if(*indata == ',')
  {
   gps_datalen[dotnum] =  dlen;      //','前面的数据长度
   gprs_straddr[dotnum] = indata;  //','地址
   dlen = 0;
   dotnum ++;
  }
  //   else if(*indata == 0x0d)
  //   {
  //    gps_datalen[dotnum] = dlen;
  //    return dotnum;
  //    break;
  //   }
  else if(*indata == '\0')
  {
   gps_datalen[dotnum] = dlen;
   return dotnum;

  }
  indata ++;
 }
 return 0;

}

// old
//void doClientRequest(int client_sock)
//{
//        char buff[BUFSIZ];
//        int result;
//        fd_set readfd;//,writefd;
//        struct timeval tv;
//        tv.tv_sec=1;
//        tv.tv_usec=0;       
//        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))
//                        {
//                                /*客户端接收数据事件*/
//                                result=recv(client_sock,buff,BUFSIZ,0);
//                                if(result>0)
//                                {
//                                        printf("accepte message success:%s ,counter %d byte\n",buff,result);
//                                }else{
//                                        if(result<0)
//                                        {
//                                                printf("message recive failse\n");
//                                        }else{
//                                                printf("%d client customer exit\n",client_sock);
//                                        }
//                                        printf("exit recv data thread......\n");
//                                        break; //break for ,exit thread
//                                }
//                        }
//                }
//                       
//        }
//}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值