/*发送透明传输数据*/ bool CVechileMgr::SendTransparentMsg(_stVechile *p , int ncount,unsigned short wType) { if( ncount <= 0 ) { return false ; } DataBuffer transport_buf; TransHeader header; int nLen = _logistics->BuildTransportData(wType,transport_buf); OUT_HEX(NULL, 0, "Transport", transport_buf.getBuffer(),transport_buf.getLength()); BuildHeader(header.header, 0x900,nLen, p); DataBuffer sendbuf; sendbuf.writeBlock(&header, sizeof(header)); sendbuf.writeBlock(transport_buf.getBuffer(), transport_buf.getLength()); unsigned short mlen = (sendbuf.getLength()-sizeof(GBheader)) & 0x03FF ; sendbuf.fillInt16( mlen, 3 ) ; GBFooter footer ; sendbuf.writeBlock(&footer, sizeof(footer) ) ; if ( ! Send5BData( p->fd_, sendbuf.getBuffer(), sendbuf.getLength() ) ) { p->car_state_ = OFF_LINE ; return false ; } p->lgs_time_ = share::Util::currentTimeUsec() ; return true ; }
void MsgClient::HandleInnerData( socket_t *sock, const char *data, int len ) { User user = _online_user.GetUserBySocket( sock ) ; if ( user._user_id.empty() ) { OUT_ERROR( sock->_szIp, sock->_port, "CAIS" , "find fd %d user failed, data %s", sock->_fd, data ) ; return ; } user._last_active_time = time(NULL) ; _online_user.SetUser( user._user_id, user ) ; string line( data, len ) ; vector<string> vec ; if ( ! splitvector( line, vec, " " , 6 ) ){ OUT_ERROR( sock->_szIp, sock->_port, user._user_name.c_str() , "fd %d data error: %s", sock->_fd, data ) ; return ; } DataBuffer buf ; string head = vec[0] ; string seqid = vec[1] ; string macid = vec[2] ; string code = vec[3] ; // 通信码,对于点名数据的区分 string cmd = vec[4] ; string val = vec[5] ; if ( head == "CAITS" ) { if( cmd == "U_REPT" ){ // 上报类消息处理 _convert->convert_urept( macid , val , buf , ( code == "201") ) ; } else if( cmd == "D_CTLM" ) { // ToDo: 控制类消息处理 } else if( cmd == "D_SNDM" ) { // ToDo : 消息发送的处理 } else { OUT_WARNING( sock->_szIp, sock->_port, user._user_name.c_str() , "except message:%s", (const char*)data ) ; } } else { // 处理通应应答消息 _convert->convert_comm( seqid, macid, val, buf ) ; } if( buf.getLength() > 0 ) { // 添加用户会话中 _session.AddSession( macid, user._user_id ) ; // 发送指定的地区用户 _pEnv->GetPasClient()->HandleData( buf.getBuffer(), buf.getLength() ) ; } }
void MsgClient::HandleInnerData( socket_t *sock, const char *data, int len) { const char *ip = sock->_szIp; unsigned short port = sock->_port; User user = _online_user.GetUserBySocket( sock ) ; if ( user._user_id.empty() ) { OUT_ERROR( ip, port, NULL, "get fd %d user failed", sock->_fd ) ; return ; } // CAITS 0_0 MACID 0 U_REPT {TYPE:5,18:上下线状态/前置机服务器ID/管道控制服务ID/消息服务器id} string line(data, len); vector<string> vec; if ( !splitvector( line, vec, " ", 6 ) ) { OUT_ERROR( ip, port, user._user_name.c_str() , "fd %d data error: %s", sock->_fd, data ); return; } string macid = vec[2] ; if ( macid.empty() ){ OUT_ERROR( ip, port, user._user_name.c_str(), "fd %d macid empty", sock->_fd ) ; return ; } string vechile ; if ( ! _macid2carnum.GetSession( macid, vechile ) ) { OUT_ERROR( ip, port, user._user_name.c_str(), "fd %d get vechile num by mac id %s failed", macid.c_str() ) ; return ; } string acode ; DataBuffer buf ; // 转换控制指令 if (vec[4] == "D_CTLM") { // 转换控制指令 _convert->convert_ctrl( vec[1], macid , vec[5] , vechile, buf , acode ) ; } else if ( vec[4] == "D_SNDM" ) { OUT_INFO( ip, port, user._user_name.c_str(), "D_SNDM"); //xifengming _convert->convert_sndm( vec[1] , macid, vec[5], vechile, buf, acode ) ; } if ( ! acode.empty() && buf.getLength() > 0 ) { // 下发给PAS对应的接入商 _pEnv->GetPasServer()->HandlePasDown( acode.c_str(), buf.getBuffer(), buf.getLength() ) ; } user._last_active_time = time(NULL); _online_user.SetUser(user._user_id, user); }
/** * Send an I/O control request to the Alfresco CIFS server, receive and validate the response * * @param ctlCode const unsigned int * @param reqbuf DataBuffer& * @param respbuf DataBuffer& */ void AlfrescoInterface::sendIOControl( const unsigned int ctlCode, DataBuffer& reqbuf, DataBuffer& respbuf) { // Send the I/O control request, receive the response DWORD retLen = 0; BOOL res = DeviceIoControl( m_handle, ctlCode, reqbuf.getBuffer(), reqbuf.getLength(), respbuf.getBuffer(), respbuf.getBufferLength(), &retLen, (LPOVERLAPPED) NULL); if ( res) { // Validate the reply signature if ( retLen >= IOSignatureLen) { respbuf.setLength(retLen); respbuf.setEndOfBuffer(); String sig = respbuf.getString(IOSignatureLen, false); if ( sig.equals(IOSignature) == false) throw Exception( L"Invalid I/O control signature received"); } } else throw Exception( L"Send I/O control error", Integer::toString( GetLastError())); }
//-----------------------------缓存数据处理接口----------------------------------------- // 处理外部数据 int PasServer::HandleQueue(const char *uid, void *buf, int len, int msgid) { OUT_PRINT( NULL, 0, NULL, "HanldeQueue msg id %d , accesscode %s , data length %d" , msgid, uid, len ); switch (msgid) { case DATA_FILECACHE: // 用户不在线数据缓存 { // 如果数据长度不正确直接返回 if (len < (int) sizeof(Header)) { OUT_ERROR( NULL, 0, NULL, "HandleQueue filecache data length %d error", len ); return IOHANDLE_ERRDATA; } OUT_PRINT( NULL, 0, NULL, "HandleQueue %s" , _proto_parse.Decoder( (const char *)buf, len ).c_str() ); Header *header = (Header *) buf; unsigned short msg_type = ntouv16(header->msg_type); // 如果不为扩展类消息 if (msg_type != DOWN_EXG_MSG) { return IOHANDLE_ERRDATA; } // 如果为扩展类消息 ExgMsgHeader *exg = (ExgMsgHeader*) ((const char *) (buf) + sizeof(Header)); unsigned short data_type = ntouv16( exg->data_type ); if (data_type != DOWN_EXG_MSG_CAR_LOCATION) { return IOHANDLE_ERRDATA; } DownExgMsgCarLocation *req = (DownExgMsgCarLocation *) buf; DownExgMsgHistoryArcossareaHeader msg; memcpy(&msg, buf, sizeof(msg)); msg.exg_msg_header.data_length = ntouv32( sizeof(char) + sizeof(GnssData) ); msg.exg_msg_header.data_type = ntouv16(DOWN_EXG_MSG_HISTORY_ARCOSSAREA); msg.header.msg_len = ntouv32( sizeof(msg) + sizeof(char) + sizeof(GnssData) + sizeof(Footer) ); msg.cnt_num = 0x01; DataBuffer dbuf; dbuf.writeBlock(&msg, sizeof(msg)); dbuf.writeBlock(&req->gnss, sizeof(GnssData)); Footer footer; dbuf.writeBlock(&footer, sizeof(footer)); if (!SendDataToPasUser(atoi(uid), dbuf.getBuffer(), dbuf.getLength())) { OUT_ERROR( NULL, 0, NULL, "DOWN_EXG_MSG_HISTORY_ARCOSSAREA:%s" , msg.exg_msg_header.vehicle_no ); return IOHANDLE_FAILED; } OUT_SEND( NULL, 0, NULL, "DOWN_EXG_MSG_HISTORY_ARCOSSAREA:%s" , msg.exg_msg_header.vehicle_no ); } break; } return IOHANDLE_SUCCESS; }
// 处理下载的后的图片数据 void MsgClient::ProcessResp( unsigned int seqid, const char *data, const int nlen , const int err ) { // 处理数据 if ( data == NULL || err != HTTP_CALL_SUCCESS || nlen == 0 ) { OUT_ERROR( NULL, 0, "Pic" , "pic seqid %u, error %d" , seqid, err ) ; return ; } /** char szfile[128] = {0}; sprintf( szfile, "./%u.jpg", seqid ) ; WriteFile( szfile, data, nlen ) ; OUT_INFO( NULL, 0, "PHOTO", "write file %s length %d", szfile, nlen ) ; */ char szKey[512] = {0} ; _pEnv->GetCacheKey( seqid, szKey ) ; int dlen = 0 ; char *msg = _pEnv->GetMsgCache()->GetData( szKey, dlen ) ; if ( msg == NULL ) { OUT_ERROR( NULL, 0, "Pic" , "pic get key %s cache failed" , szKey ) ; return ; } // 转换照片的结构体 UpCtrlMsgTakePhotoAck *ack = ( UpCtrlMsgTakePhotoAck * ) msg; int len = sizeof(UpCtrlMsgTakePhotoAck) + sizeof(Footer) + nlen ; ack->header.msg_len = ntouv32( len ) ; ack->ctrl_msg_header.data_length = ntouv32( sizeof(UpCtrlMsgTakePhotoBody) + nlen ) ; ack->ctrl_photo_body.photo_len = ntouv32( nlen ) ; DataBuffer dbuf ; dbuf.writeBlock( ack, sizeof(UpCtrlMsgTakePhotoAck) ) ; if ( nlen > 0 ) { dbuf.writeBlock( data, nlen ) ; } Footer footer ; dbuf.writeBlock( &footer, sizeof(footer) ) ; // 取得接入码信息 unsigned int accesscode = ntouv32( ack->header.access_code ) ; // 发送拍照的照片数据 _pEnv->GetPasClient()->HandlePasUpData( accesscode, dbuf.getBuffer(), dbuf.getLength() ) ; OUT_SEND( NULL, 0, NULL, "UP_CTRL_MSG_TAKE_PHOTO_ACK:%s, picture length %d", ack->ctrl_msg_header.vehicle_no , nlen ) ; _pEnv->GetMsgCache()->FreeData( msg ) ; }
// 转换数据 char * PConvert::convert_urept( const string &key, const string &ome, const string &phone, const string &val, int &len , unsigned int &msgid , unsigned int &type ) { int ntype = 0 ; MapString map ; if ( ! get_map_header( val, map, ntype ) ) { OUT_ERROR( NULL, 0, NULL, "PConvert::convert_urept get map header failed") ; return NULL ; } type = METHOD_OTHER ; char *buf = NULL ; switch(ntype) { case 0: //路径和报警数据 位置汇报 case 1: { UpExgMsgRealLocation msg; msg.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; msg.header.msg_len = ntouv32( sizeof(UpExgMsgRealLocation) ) ; //msg.header.access_code = ntouv32(access_code); //msg.exg_msg_header.vehicle_color = car_color; //safe_memncpy( msg.exg_msg_header.vehicle_no, car_num.c_str() , sizeof(msg.exg_msg_header.vehicle_no) ) ; msg.exg_msg_header.data_length = ntouv32( sizeof(GnssData) ) ; if ( ! convert_gps_info( map, msg.gnss_data ) ) { OUT_ERROR( NULL, 0, phone.c_str(), "PConvert::convert_urept convert gps failed" ) ; return NULL ; } len = sizeof(UpExgMsgRealLocation) ; buf = new char[len+1]; memset( buf, 0, len+1 ); memcpy( buf, &msg, len ); msgid = UP_EXG_MSG_REAL_LOCATION ; } break; case 2: // 行驶记录仪 { int ntemp = 0; //得到命令 if (!get_map_integer(map,"70",ntemp)){ OUT_ERROR( NULL, 0, phone.c_str(), "UP_CTRL_MSG_TAKE_TRAVEL_ACK get command_type failed" ) ; return NULL ; } string temp = ""; //得到行驶记录仪数据 Base64 编码 if (!get_map_string(map,"61",temp)) { OUT_ERROR( NULL, 0, phone.c_str(), "UP_CTRL_MSG_TAKE_TRAVEL_ACK get travel data failed" ) ; return NULL ; } int dlen = 0 ; char *ptr = _pEnv->GetMsgCache()->GetData( key.c_str(), dlen ) ; UpCtrlMsgTaketravel msg; UpCtrlMsgTaketravel *resp = NULL ; if ( ptr == NULL ) { msg.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; msg.header.msg_type = ntouv16( UP_CTRL_MSG ) ; msg.ctrl_msg_header.data_type = ntouv16( UP_CTRL_MSG_TAKE_TRAVEL_ACK ) ; msg.command_type = ntemp; resp = &msg ; } else { if ( dlen < (int) sizeof(UpCtrlMsgTaketravel) ) { OUT_ERROR( NULL, 0, phone.c_str(), "UP_CTRL_MSG_TAKE_TRAVEL_ACK get msg cache length failed, length %d" , dlen ) ; return NULL ; } resp = ( UpCtrlMsgTaketravel *) ptr ; } // 如果为了过检测试,因为测试软件的不允许插入特殊字符,为保证通过,就将它替换为假数据处理 if ( _istester & 0x01 ) { OUT_INFO( NULL, 0, phone.c_str(), "UP_CTRL_MSG_TAKE_TRAVEL_ACK tester travel data" ) ; const char szbuff[] = {0x55,0x7a,0x01,0x00,0x03,0x00,0x00,0x00,0x15,0x01} ; len = sizeof(UpCtrlMsgTaketravel)+ sizeof(szbuff) + sizeof(Footer) ; resp->ctrl_msg_header.data_length = ntouv32( sizeof(char) + sizeof(int) + sizeof(szbuff) ) ; resp->header.msg_len = ntouv32( len ) ; resp->travel_length = ntouv32( sizeof(szbuff) ) ; buf = new char[len+1]; memset(buf, 0, len+1); memcpy(buf, resp, sizeof(msg) ); memcpy( buf + sizeof(msg), szbuff , sizeof(szbuff) ) ; Footer footer ; memcpy( buf + sizeof(msg) + sizeof(szbuff), &footer, sizeof(footer) ) ; } else { CBase64 base64; base64.Decode(temp.c_str(),temp.length()) ; len = sizeof(UpCtrlMsgTaketravel)+ base64.GetLength() + sizeof(Footer) ; resp->ctrl_msg_header.data_length = ntouv32( sizeof(char) + sizeof(int) + base64.GetLength() ) ; resp->header.msg_len = ntouv32( len ) ; resp->travel_length = ntouv32( base64.GetLength() ) ; buf = new char[len+1]; memset(buf, 0, len+1); memcpy(buf, resp, sizeof(msg) ); if ( base64.GetLength() > 0 ) { memcpy( buf + sizeof(msg), base64.GetBuffer() , base64.GetLength() ) ; } Footer footer ; memcpy( buf + sizeof(msg) + base64.GetLength(), &footer, sizeof(footer) ) ; } msgid = UP_CTRL_MSG_TAKE_TRAVEL_ACK ; if ( ptr != NULL ) { // 释放数据 _pEnv->GetMsgCache()->FreeData( ptr ) ; } } break; case 3: // 拍照上传图片处理,这里拍照特殊处理一下 { string temp ; // 取图片的URL的相对地址 if ( ! get_map_string( map, "125" , temp ) ) { get_map_string( map, "203", temp ) ; } // 如果没有取着图片的地址 if ( temp.empty() ) { OUT_ERROR( NULL, 0, phone.c_str(), "UP_CTRL_MSG_TAKE_PHOTO_ACK get file path failed" ) ; return NULL ; } // 从ome_phone_msgid中取得下发的指令消息 char szKey[256] = {0} ; sprintf( szKey, "%s_%s_%d" , ome.c_str(), phone.c_str(), UP_CTRL_MSG_TAKE_PHOTO_ACK ) ; int nlen = 0 ; char *pbuf = _pEnv->GetMsgCache()->GetData( szKey, nlen ) ; if ( pbuf == NULL ) { OUT_ERROR( NULL, 0, phone.c_str(), "UP_CTRL_MSG_TAKE_PHOTO_ACK get data from cache failed, key %s" , szKey ) ; return NULL ; } UpCtrlMsgTakePhotoAck *ack = ( UpCtrlMsgTakePhotoAck * ) pbuf; if ( _istester & 0x02 ) { GnssData &gps = ack->ctrl_photo_body.gps ; // 1:65522247,2:18072200,20:5,24:100,3:670,4:20120329/180448,5:30,6:802,7:670,8:6147,9:125000 gps.lon = ntouv32( 109203745 ) ; gps.lat = ntouv32( 30120333 ) ; gps.vec1 = ntouv16( 100 ) ; // 速度808中为1/10m/s time_t ntime = time(NULL) ; struct tm local_tm; struct tm *tm = localtime_r( &ntime, &local_tm ) ; gps.date[3] = ( tm->tm_year + 1900) % 256 ; gps.date[2] = ( tm->tm_year + 1900) / 256 ; gps.date[1] = tm->tm_mon + 1 ; gps.date[0] = tm->tm_mday ; gps.time[0] = tm->tm_hour ; gps.time[1] = tm->tm_min ; gps.time[2] = tm->tm_sec ; gps.direction = ntouv16( 0 ) ; gps.state = ntouv32(0x03) ; gps.alarm = ntouv32(0) ; gps.vec3 = ntouv32( 0 ) ; } else { // 将获到GPS位置数据填充入结构体中 convert_gps_info( map, ack->ctrl_photo_body.gps ) ; } // 从本地读取一次图片 int piclen = 0 ; char *picdata = NULL ; // 如果本地图片路径为空就从HTTP取图片 if ( ! _picdir.empty() ) { char szpath[1024] = {0}; sprintf( szpath, "%s/%s", _picdir.c_str(), temp.c_str() ) ; picdata = ReadFile( szpath , piclen ) ; } // 如果文件在本机直接读取 if ( picdata != NULL && piclen > 0 ) { // 直接从本机读取图片 ack->header.msg_len = ntouv32( sizeof(UpCtrlMsgTakePhotoAck) + sizeof(Footer) + piclen ) ; ack->ctrl_msg_header.data_length = ntouv32( sizeof(UpCtrlMsgTakePhotoBody) + piclen ) ; ack->ctrl_photo_body.photo_len = ntouv32( piclen ) ; DataBuffer dbuf ; dbuf.writeBlock( ack, sizeof(UpCtrlMsgTakePhotoAck) ) ; if ( piclen > 0 ) { dbuf.writeBlock( picdata, piclen ) ; } Footer footer ; dbuf.writeBlock( &footer, sizeof(footer) ) ; // 取得接入码信息 unsigned int accesscode = ntouv32( ack->header.access_code ) ; // 发送拍照的照片数据 _pEnv->GetPasClient()->HandlePasUpData( accesscode, dbuf.getBuffer(), dbuf.getLength() ) ; FreeBuffer( picdata ) ; OUT_SEND( NULL, 0, NULL, "UP_CTRL_MSG_TAKE_PHOTO_ACK:%s, picture length %d, path: %s", ack->ctrl_msg_header.vehicle_no , nlen , temp.c_str() ) ; } else { // 从网络读取文件 // 取得新序号的ID值 unsigned int seqid = _pEnv->GetSequeue() ; _pEnv->GetCacheKey( seqid, szKey ) ; // 重新放入新序号队列中 _pEnv->GetMsgCache()->AddData( szKey, pbuf , nlen ) ; // 从网络中读取图片数据 ((IMsgClient*)_pEnv->GetMsgClient())->LoadUrlPic( seqid , temp.c_str() ) ; OUT_SEND( NULL, 0, NULL, "UP_CTRL_MSG_TAKE_PHOTO_ACK picture path %s", temp.c_str() ) ; } _pEnv->GetMsgCache()->FreeData( pbuf ) ; } break ; /* case 5: { int result = 0; if (!get_map_integer(map, "18", result) || result != 1) { return NULL; } UpExgMsgRegister msg; msg.header.msg_seq = ntouv32(_seq_gen.get_next_seq()); msg.header.msg_len = ntouv32(sizeof(UpExgMsgRegister)); msg.header.msg_type = ntouv16(UP_EXG_MSG); msg.exg_msg_header.data_type = ntouv16(UP_EXG_MSG_REGISTER); //子业务类型 msg.exg_msg_header.data_length = ntouv32(sizeof(UpExgMsgRegister) - sizeof(Header) - sizeof(ExgMsgHeader) - sizeof(Footer)); sprintf(msg.platform_id, "%s", PLATFORM_ID); len = sizeof(UpExgMsgRegister); buf = new char[len + 1]; memset(buf, 0, len + 1); memcpy(buf, &msg, len); msgid = UP_EXG_MSG_REGISTER; type = METHOD_REG; } break; */ case 8: // 主动上报驾驶员信息采集 { UpExgMsgReportDriverInfo msg; msg.header.msg_seq = ntouv32( _seq_gen.get_next_seq()); msg.header.msg_len = ntouv32(sizeof(UpExgMsgReportDriverInfo)); msg.header.msg_type = ntouv16( UP_EXG_MSG); // msg.header.access_code = access_code; msg.exg_msg_header.data_type = ntouv16(UP_EXG_MSG_REPORT_DRIVER_INFO); msg.exg_msg_header.data_length = ntouv32(sizeof(UpExgMsgReportDriverInfo) - sizeof(Header) - sizeof(ExgMsgHeader) - sizeof(Footer)); string temp; //驾驶员姓名 if (get_map_string(map, "110" , temp )) { safe_memncpy( msg.driver_name,temp.c_str(), sizeof(msg.driver_name)); } //驾驶员编码 if ( get_map_string(map, "111" , temp )) { safe_memncpy( msg.driver_id,temp.c_str(), sizeof(msg.driver_id)); } //从业资格证编码 if ( get_map_string(map, "112" , temp )) { safe_memncpy( msg.licence,temp.c_str(), sizeof(msg.licence)); } //发证机构名称 if ( get_map_string(map, "113" , temp )) { safe_memncpy( msg.org_name,temp.c_str(), sizeof(msg.org_name)); } //OUT_SEND(NULL, 0, NULL, "UpExgMsgReportDriverInfo:%s",car_num.c_str()); len = sizeof(UpExgMsgReportDriverInfo) ; buf = new char[len+1]; memset(buf, 0, len+1); memcpy(buf, &msg, len); msgid = UP_EXG_MSG_REPORT_DRIVER_INFO ; } break; case 35: // 主动上报电子运单 { UpExgMsgReportEwaybillInfo msg; msg.header.msg_seq = ntouv32( _seq_gen.get_next_seq()); msg.header.msg_type = ntouv16( UP_EXG_MSG); // msg.header.access_code = access_code; msg.exg_msg_header.data_type = ntouv16(UP_EXG_MSG_REPORT_EWAYBILL_INFO); string temp = ""; if (get_map_string(map,"87",temp)) { //电子运单内容 CBase64 base64; base64.Decode(temp.c_str(),temp.length()); len = sizeof(UpExgMsgReportEwaybillInfo)+ base64.GetLength()+ sizeof(Footer); msg.exg_msg_header.data_length = ntouv32( sizeof(int) + base64.GetLength() ) ; msg.ewaybill_length = ntouv32( base64.GetLength() ) ; msg.header.msg_len = ntouv32( len ) ; buf = new char[len+1]; memcpy( buf, &msg, sizeof(msg) ); if ( base64.GetLength() > 0 ) { memcpy( buf + sizeof(msg), base64.GetBuffer(), base64.GetLength() ); } // 添加结束标记 Footer footer ; memcpy( buf + sizeof(msg) + base64.GetLength(), &footer, sizeof(footer) ) ; } msgid = UP_EXG_MSG_REPORT_EWAYBILL_INFO ; // OUT_SEND(NULL, 0, NULL, "UP_EXG_MSG_Ewaybill:%s", car_num.c_str()); } break; /* case 36: // 终端注册,这里暂时只处理终端鉴权 { int result = 0 ; if ( get_map_integer( map, "45", result ) ) { // 如果终端注册失败就直接返回了。 if ( result != 0 ) { return NULL ; } } UpExgMsgRegister msg; msg.header.msg_seq = ntouv32( _seq_gen.get_next_seq()); msg.header.msg_len = ntouv32( sizeof(UpExgMsgRegister) ) ; msg.header.msg_type = ntouv16( UP_EXG_MSG); msg.exg_msg_header.data_type = ntouv16( UP_EXG_MSG_REGISTER ) ; //子业务类型 //msg.exg_msg_header.vehicle_color = car_color ; //safe_memncpy( msg.exg_msg_header.vehicle_no, car_num.c_str(), sizeof(msg.exg_msg_header.vehicle_no) ) ; msg.exg_msg_header.data_length = ntouv32( sizeof(UpExgMsgRegister) - sizeof(Header) - sizeof(ExgMsgHeader) - sizeof(Footer) ) ; sprintf( msg.platform_id , "%s" , PLATFORM_ID ) ; string temp ; // 取得制造产商ID if ( get_map_string( map, "42" , temp ) ) { safe_memncpy( msg.producer_id, temp.c_str(), sizeof(msg.producer_id) ) ; } // 取得终端类型 if ( get_map_string( map, "43" , temp ) ) { safe_memncpy( msg.terminal_model_type, temp.c_str(), sizeof(msg.terminal_model_type) ) ; } // 取得终端ID if ( get_map_string( map, "44" , temp ) ) { safe_memncpy( msg.terminal_id, temp.c_str(), sizeof(msg.terminal_id) ) ; } // 取得手机SIM号 if ( phone.length() > 0 ) { //reverse_copy(msg.terminal_simcode, sizeof(msg.terminal_simcode), temp.c_str(), 0 ) ; // 前面补零拷贝 reverse_copy(msg.terminal_simcode, sizeof(msg.terminal_simcode), phone.c_str(), 0 ); } len = sizeof(UpExgMsgRegister) ; buf = new char[len+1] ; memset(buf, 0, len+1) ; memcpy(buf, &msg, len) ; msgid = UP_EXG_MSG_REGISTER ; } break; case 38: //终端鉴权后,要异步回调通过http,通过pcc 提交到Service 请求sim卡号,终端类型 { int result = 0 ; if ( get_map_integer( map, "48", result ) ) { // 如果终端鉴权失败就直接返回了。 if ( result != 0 ) { return NULL ; } } UpExgMsgRegister msg; msg.header.msg_seq = ntouv32( _seq_gen.get_next_seq()); msg.header.msg_len = ntouv32( sizeof(UpExgMsgRegister) ) ; msg.header.msg_type = ntouv16( UP_EXG_MSG); msg.exg_msg_header.data_type = ntouv16(UP_EXG_MSG_REGISTER) ; //子业务类型 msg.exg_msg_header.data_length = ntouv32( sizeof(UpExgMsgRegister) - sizeof(Header) - sizeof(ExgMsgHeader) - sizeof(Footer)); sprintf( msg.platform_id , "%s" , PLATFORM_ID ) ; len = sizeof(UpExgMsgRegister) ; buf = new char[len+1] ; memset(buf, 0, len+1) ; memcpy(buf, &msg, len) ; msgid = UP_EXG_MSG_REGISTER ; type = METHOD_REG ; } break; */ default: { //OUT_ERROR( NULL, 0, phone.c_str(), "PConvert::convert_urept not support %s", val.c_str() ) ; } break ; } return buf ; }
// 转换监管协议 char * PConvert::convert_lprov( const string &key, const string &seqid, const string &val , int &len, string &areacode ) { MapString map ; if ( ! parse_jkpt_value( val, map ) ) { OUT_ERROR( NULL, 0, NULL, "parse data %s failed", val.c_str() ) ; return NULL ; } string stype ; if ( ! get_map_string( map , "TYPE", stype ) ) { OUT_ERROR( NULL, 0, NULL, "get data %s type failed", val.c_str() ) ; return NULL ; } // 取得省域ID if ( ! get_map_string( map, "AREA_CODE", areacode ) ) { OUT_ERROR( NULL, 0, NULL, "get area code failed, %s", val.c_str() ) ; return NULL ; } char *buf = NULL ; // AREA_CODE:省代码,CARNO:车牌颜色_车牌号,ACCESS_CODE:运营商接入码,TYPE:XXX,k1:v1... if ( stype == "D_PLAT" ) { string sval ; // 如果为平台查岗消息处理 if ( get_map_string( map, "PLATQUERY" , sval ) ) { // 查岗对象的类型(1:当前连接的下级平台,2:下级平台所属单一业户,3:下级平台所属所有业户)|查岗对象的ID|信息ID|应答内容" vector<string> vec ; if ( ! splitvector( sval, vec, "|" , 0 ) ) { OUT_ERROR( NULL, 0, areacode.c_str(), "split vector failed, sval %s" , sval.c_str() ) ; return NULL ; } // 如果拆分个数小于四个则直接返回 if ( vec.size() < 4 ) { OUT_ERROR( NULL, 0, areacode.c_str(), "split vector param too less, value %s" , sval.c_str() ) ; return NULL ; } int dlen = 0 ; char *ptr = _pEnv->GetMsgCache()->GetData( key.c_str(), dlen , false ) ; if ( ptr == NULL ) { OUT_ERROR( NULL, 0, areacode.c_str(), "get plat msg failed , key %s" , key.c_str() ) ; return NULL ; } string content = vec[3] ; CBase64 base; if ( base.Decode( content.c_str(), content.length() ) ) { content = base.GetBuffer() ; } len = sizeof(UpPlatformMsgPostQueryAck) + content.length() + sizeof(Footer) ; buf = new char[len+1] ; // 处理平台查岗的消息 UpPlatformMsgPostQueryAck *rsp = (UpPlatformMsgPostQueryAck *) ptr ; rsp->header.msg_len = ntouv32( len ) ; rsp->up_platform_msg.data_length = ntouv32( sizeof(UpPlatformMsgpostqueryData) + content.length() ) ; rsp->up_platform_post.msg_len = ntouv32( content.length() ) ; rsp->up_platform_post.object_type = atoi( vec[0].c_str() ) ; safe_memncpy( rsp->up_platform_post.object_id, vec[1].c_str(), sizeof(rsp->up_platform_post.object_id) ) ; rsp->up_platform_post.info_id = ntouv32( atoi(vec[2].c_str()) ) ; memcpy( buf, rsp, sizeof(UpPlatformMsgPostQueryAck) ) ; memcpy( buf+sizeof(UpPlatformMsgPostQueryAck) , content.c_str(), content.length() ) ; Footer footer ; memcpy( buf+sizeof(UpPlatformMsgPostQueryAck) + content.length(), &footer, sizeof(footer) ) ; OUT_PRINT( NULL, 0, areacode.c_str(), "platquery message %s", content.c_str() ) ; return buf ; } // 平台间消息 if ( get_map_string( map, "PLATMSG", sval ) ) { // 从缓存中取数据, 针对平台间消息和平台查岗暂时不回收资源 char *ptr = _pEnv->GetMsgCache()->GetData( key.c_str(), len , false ) ; if ( buf == NULL ) { OUT_ERROR( NULL, 0, areacode.c_str(), "get msg from cache failed, key %s", key.c_str() ) ; return NULL ; } // 重新拷贝处理 buf = new char[len+1] ; memset( buf, 0, len + 1 ) ; memcpy( buf, ptr, len ) ; // 处理平台消息的ID UpPlatFormMsgInfoAck *ack = (UpPlatFormMsgInfoAck *) buf ; ack->info_id = ntouv32( atoi(sval.c_str()) ) ; return buf ; } } else { // 除平台查岗处理 string macid ; // 取得车牌颜色和车牌号 if ( ! get_map_string( map, "CARNO" , macid ) ) { OUT_ERROR( NULL, 0, areacode.c_str(), "get carno failed, %s", val.c_str() ) ; return NULL ; } unsigned char carcolor = 0 ; string carnum ; // 通过MACID取得车颜色和车牌号 if ( ! get_carinfobymacid( macid, carcolor, carnum ) ) { OUT_ERROR( NULL, 0, areacode.c_str(), "get car color and car num by macid failed, %d" , macid.c_str() ) ; return NULL ; } string sval ; // 如果为报警业务 if ( stype == "D_WARN" ) { // 报警督办 if ( get_map_string( map, "WARNTODO", sval ) ) { buf = _pEnv->GetMsgCache()->GetData( key.c_str(), len ) ; if ( buf == NULL ) { OUT_ERROR( NULL, 0, areacode.c_str(), "get msg data failed, key %s, macid %s" , key.c_str(), macid.c_str() ) ; return NULL ; } UpWarnMsgUrgeTodoAck *rsp = ( UpWarnMsgUrgeTodoAck *) buf ; rsp->result = atoi(sval.c_str()) ; return buf ; } // 处理上报报警 if ( get_map_string( map, "WARNINFO" , sval ) ) { // 报警信息来源(1:车载终端,2:企业监控平台,3:政府监管平台,9:其它)|报警类型(详见5.3“报警类型编码表”)|报警时间(UTC时间格式)|信息ID|报警信息内容 vector<string> vec ; // 处理所有逗号分割处理 if ( ! splitvector( sval , vec, "|" , 0 ) ) { OUT_ERROR( NULL, 0, areacode.c_str(), "WARNINFO split vector error, key %s, macid %s, value: %s" , key.c_str(), macid.c_str() , sval.c_str() ) ; return false ; } if ( vec.size() < 5 ) { OUT_ERROR( NULL, 0, areacode.c_str(), "WARNINFO arg too less error, key %s, macid %s, value: %s" , key.c_str(), macid.c_str() , sval.c_str() ) ; return false ; } int nlen = vec[4].length() ; len = sizeof(UpWarnMsgAdptInfoHeader) + sizeof(UpWarnMsgAdptInfoBody) + nlen + sizeof(Footer) ; UpWarnMsgAdptInfoHeader req ; req.header.msg_len = ntouv32( len ) ; // 修正长度不正 req.header.msg_type = ntouv16( UP_WARN_MSG ) ; req.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; req.warn_msg_header.vehicle_color = carcolor ; safe_memncpy( req.warn_msg_header.vehicle_no, carnum.c_str(), sizeof(req.warn_msg_header.vehicle_no) ) ; req.warn_msg_header.data_type = ntouv16( UP_WARN_MSG_ADPT_INFO ) ; req.warn_msg_header.data_length = ntouv32( sizeof(UpWarnMsgAdptInfoBody) + nlen ) ; UpWarnMsgAdptInfoBody body ; body.warn_src = atoi( vec[0].c_str() ) ; body.warn_type = ntouv16( atoi(vec[1].c_str()) ) ; body.warn_time = ntouv64( atoi64(vec[2].c_str()) ) ; body.info_id = ntouv32( atoi(vec[3].c_str()) ) ; body.info_length = ntouv32( nlen ) ; int offset = 0 ; buf = new char[len+1] ; memcpy( buf+offset, &req, sizeof(req) ) ; offset += sizeof(req) ; memcpy( buf+offset, &body, sizeof(body) ) ; offset += sizeof(body) ; memcpy( buf+offset, vec[4].c_str(), nlen ) ; offset += nlen ; Footer footer ; memcpy( buf+offset, &footer, sizeof(footer) ) ; return buf ; } // 处理主动上报报警结果 if ( get_map_string( map, "UPWARN", sval ) ) { // 报警信息ID|报警处理结果(0:处理中,1:已处理完毕,2:不作处理,3:将来处理) size_t pos = sval.find( "|" ) ; if ( pos == string::npos ) { OUT_ERROR( NULL, 0, areacode.c_str(), "upwarn result command error, value: %s" , val.c_str() ) ; return NULL ; } // 组装主动上报处理理结果的数据包 UpWarnMsgAdptTodoInfo req ; req.header.msg_len = ntouv32( sizeof(UpWarnMsgAdptTodoInfo) ) ; req.header.msg_type = ntouv16( UP_WARN_MSG ) ; req.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; req.warn_msg_header.vehicle_color = carcolor ; safe_memncpy( req.warn_msg_header.vehicle_no, carnum.c_str(), sizeof(req.warn_msg_header.vehicle_no) ) ; req.warn_msg_header.data_type = ntouv16( UP_WARN_MSG_ADPT_TODO_INFO ) ; req.warn_msg_header.data_length = ntouv32( sizeof(WarnMsgAdptTodoInfoBody) ) ; req.warn_msg_body.info_id = ntouv32( atoi( sval.c_str() ) ) ; req.warn_msg_body.result = atoi( sval.substr(pos+1).c_str() ) ; len = sizeof(req) ; buf = new char[len+1] ; memcpy( buf, &req, sizeof(req) ) ; return buf ; } } else if ( stype == "D_MESG" ) { // 如果下发申请交换车辆信息 if ( get_map_string( map, "MONITORSTARTUP" , sval ) ) { // 开始时间(UTC时间格式)|结束时间(UTC时间格式) size_t pos = sval.find( "|" ) ; if ( pos == string::npos ) { OUT_ERROR( NULL, 0, areacode.c_str(), "down command error , value : %s" , val.c_str() ) ; return NULL ; } uint64 start = atoi64( sval.substr(0, pos).c_str() ) ; uint64 end = atoi64( sval.substr( pos+1).c_str() ) ; UpExgMsgApplyForMonitorStartup req ; req.header.msg_len = ntouv32( sizeof(req) ) ; req.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; req.exg_msg_header.vehicle_color = carcolor ; safe_memncpy( req.exg_msg_header.vehicle_no, carnum.c_str(), sizeof(req.exg_msg_header.vehicle_no) ) ; req.exg_msg_header.data_length = ntouv32( sizeof(uint64) * 2 ) ; req.start_time = ntouv64( start ) ; req.end_time = ntouv64( end ) ; len = sizeof(req) ; buf = new char[len+1] ; memcpy( buf, &req, sizeof(req) ) ; _pEnv->GetPasClient()->AddMacId2SeqId( UP_EXG_MSG_APPLY_FOR_MONITOR_STARTUP , macid.c_str(), seqid.c_str() ) ; return buf ; } // 结束车辆交换信息 if ( get_map_string( map , "MONITOREND" , sval ) ) { UpExgMsgApplyForMonitorEnd req ; req.header.msg_len = ntouv32( sizeof(req) ) ; req.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; req.exg_msg_header.vehicle_color = carcolor ; safe_memncpy( req.exg_msg_header.vehicle_no, carnum.c_str(), sizeof(req.exg_msg_header.vehicle_no) ) ; req.exg_msg_header.data_length = ntouv32( 0 ) ; len = sizeof(req) ; buf = new char[len+1] ; memcpy( buf, &req, sizeof(req) ) ; _pEnv->GetPasClient()->AddMacId2SeqId( UP_EXG_MSG_APPLY_FOR_MONITOR_END , macid.c_str(), seqid.c_str() ) ; return buf ; } // 这是平台主动下发,还有一种平台自动下发情况,补发指定时间车辆信息 if ( get_map_string( map, "HISGNSSDATA" , sval ) ) { // 开始时间(UTC时间格式)|结束时间(UTC时间格式) size_t pos = sval.find( "|" ) ; if ( pos == string::npos ) { OUT_ERROR( NULL, 0, areacode.c_str(), "down command error , value : %s" , val.c_str() ) ; return NULL ; } uint64 start = atoi64( sval.substr(0, pos).c_str() ) ; uint64 end = atoi64( sval.substr( pos+1).c_str() ) ; UpExgApplyHisGnssDataReq req ; req.header.msg_len = ntouv32( sizeof(req) ) ; req.header.msg_type = ntouv16( UP_EXG_MSG ) ; req.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; req.exg_msg_header.vehicle_color = carcolor ; safe_memncpy( req.exg_msg_header.vehicle_no, carnum.c_str(), sizeof(req.exg_msg_header.vehicle_no) ) ; req.exg_msg_header.data_length = ntouv32( sizeof(uint64) * 2 ) ; req.exg_msg_header.data_type = ntouv16( UP_EXG_MSG_APPLY_HISGNSSDATA_REQ ) ; req.start_time = ntouv64( start ) ; req.end_time = ntouv64( end ) ; len = sizeof(req) ; buf = new char[len+1] ; memcpy( buf, &req, sizeof(req) ) ; _pEnv->GetPasClient()->AddMacId2SeqId( UP_EXG_MSG_APPLY_HISGNSSDATA_REQ , macid.c_str(), seqid.c_str() ) ; return buf ; } // 处理历史数据上报 size_t pos = val.find( "HISTORY" ) ; // 取得车辆的历史位数据情况 if ( pos != string::npos ) { size_t end = val.find( "}" , pos+8 ) ; if ( end == string::npos || end < pos ){ OUT_ERROR( NULL, 0, areacode.c_str(), "HISTORY split vector error, key %s, macid %s, value: %s" , key.c_str(), macid.c_str() , val.c_str() ) ; return false; } sval = val.substr( pos+8, end - pos - 8 ) ; vector<string> vec ; // 处理所有逗号分割处理 if ( ! splitvector( sval , vec, "|" , 0 ) ) { OUT_ERROR( NULL, 0, areacode.c_str(), "HISTORY split vector error, key %s, macid %s, value: %s" , key.c_str(), macid.c_str() , sval.c_str() ) ; return false ; } int nsize = vec.size() ; UpExgMsgHistoryHeader msg ; msg.header.msg_type = ntouv16( UP_EXG_MSG ) ; msg.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; msg.exg_msg_header.vehicle_color = carcolor ; safe_memncpy( msg.exg_msg_header.vehicle_no, carnum.c_str(), sizeof(msg.exg_msg_header.vehicle_no) ) ; msg.exg_msg_header.data_type = ntouv16(UP_EXG_MSG_HISTORY_LOCATION) ; DataBuffer dbuf ; unsigned char ncount = 0 ; for ( int i = 0; i < nsize; ++ i ) { MapString gpsmap ; if ( ! split2map( vec[i] , gpsmap ) ) { continue ; } GnssData gnssdata; if ( ! convert_gps_info( gpsmap, gnssdata ) ){ continue ; } dbuf.writeBlock( &gnssdata, sizeof(GnssData) ) ; ++ ncount ; } len = sizeof(msg) + sizeof(char) + ncount*sizeof(GnssData) + sizeof(Footer) ; msg.exg_msg_header.data_length = ntouv32( sizeof(char) + ncount*sizeof(GnssData) ) ; msg.header.msg_len = ntouv32( len ) ; buf = new char[len+1] ; int offset = 0 ; memcpy( buf, &msg, sizeof(msg) ) ; offset += sizeof(msg) ; memcpy( buf+offset , &ncount, sizeof(char) ) ; offset += sizeof(char) ; memcpy( buf+offset, dbuf.getBuffer(), dbuf.getLength() ) ; offset += dbuf.getLength() ; Footer footer ; memcpy( buf+offset, &footer, sizeof(footer) ) ; return buf ; } // 接入广州809精简版监管,提交车辆静态数据,子业务类型为DOWN_EXG_MSG_CAR_INFO if (get_map_string(map, "U_BASE", sval)) { CBase64 base64; if( ! base64.Decode(sval.c_str(), sval.length())) { OUT_ERROR( NULL, 0, areacode.c_str(), "base64 decode error, value : %s" , val.c_str() ) ; return NULL; } len = sizeof(DownExgMsgCarInfoHeader) + base64.GetLength() + sizeof(Footer); buf = new char[len + 1]; DownExgMsgCarInfoHeader msg; msg.header.msg_len = ntouv32( len ) ; msg.header.msg_seq = ntouv32( _seq_gen.get_next_seq() ) ; msg.header.msg_type = ntouv16( UP_EXG_MSG ); msg.exg_msg_header.vehicle_color = carcolor ; strncpy(msg.exg_msg_header.vehicle_no, carnum.c_str(), sizeof(msg.exg_msg_header.vehicle_no)); msg.exg_msg_header.data_type = ntouv16(DOWN_EXG_MSG_CAR_INFO); msg.exg_msg_header.data_length = ntouv32(base64.GetLength()); int msgpos = 0; memcpy(buf + msgpos, &msg, sizeof(DownExgMsgCarInfoHeader)); msgpos += sizeof(DownExgMsgCarInfoHeader); memcpy(buf + msgpos, base64.GetBuffer(), base64.GetLength()); msgpos += base64.GetLength(); Footer footer ; memcpy( buf + msgpos, &footer, sizeof(footer) ) ; return buf ; } } } return NULL ; }
// 发送图片数据 bool CVechileMgr::SendLocationPic( _stVechile *p , int ncount ) { if( ncount <= 0 || p == NULL ) return false ; if ( access( _pic_url.c_str(), 0 ) != 0 ) { OUT_ERROR( NULL, 0, NULL, "check pic dir %s failed", _pic_url.c_str() ) ; return false ; } int photo_len = 0 ; char *pfile = ReadFile( _pic_url.c_str() , photo_len ) ; GBFooter footer ; GBheader header ; header.msgid = htons(0x0801) ; memcpy( header.car_id , p->car_id_ , sizeof(header.car_id) ) ; MediaUploadBody body ; body.id = 1 ; body.type = 0 ; body.mtype = 0 ; body.event = 1 ; body.chanel = 1 ; unsigned int alarm = 0 ; memcpy( &body.gps.alarm, &alarm, sizeof(unsigned int) ) ; unsigned int state = 0 ; memcpy( &body.gps.state , &state, sizeof(unsigned int) ) ; int pos = p->gps_pos_ ; pos = ++ pos % ncount ; Point &pt = _gps_vec[pos] ; body.gps.heigth = htons(100) ; body.gps.speed = htons(get_car_speed());//htons(60) ; body.gps.direction = htons(0) ; if(body.gps.speed == 0) { body.gps.state.bit0 = 0; body.gps.state.bit1 = 0; body.gps.longitude = 0 ; body.gps.latitude = 0 ; } else { body.gps.state.bit0 = 1; body.gps.state.bit1 = 1; body.gps.longitude = htonl( pt.lon ) ; body.gps.latitude = htonl( pt.lat ) ; } // 取得当前BCD的时间 get_bcd_time( body.gps.date_time ) ; DataBuffer buffer ; buffer.writeBlock( &body, sizeof(body) ) ; buffer.writeBlock( pfile, photo_len ) ; FreeBuffer( pfile ) ; // 取得需要发送的数据体 char *ptr = buffer.getBuffer() ; int len = buffer.getLength() ; // 计算分包数 int count = ( len / MAX_SPLITPACK_LEN ) + ( ( len % MAX_SPLITPACK_LEN == 0 && len > 0 ) ? 0 : 1 ) ; int offset = 0 , left = len , readlen = 0 ; // 根据分包的序号需要连续处理 unsigned short seqid = 0 ; { _seq_mutex.lock() ; p->seq_id_ = p->seq_id_ + count ; if ( p->seq_id_ < count ) { p->seq_id_ = count + 1 ; seqid = 1 ; } else { seqid = p->seq_id_ - count ; } _seq_mutex.unlock() ; } // 发送FD的数据 socket_t *fd = ( p->ufd_ != NULL ) ? p->ufd_ : p->fd_ ; // 处理分包发送数据 for ( int i = 0 ; i < count; ++ i ) { // 计算能处理长度 readlen = ( left > MAX_SPLITPACK_LEN ) ? MAX_SPLITPACK_LEN : left ; // 长度为消息内容的长度去掉头和尾 unsigned short mlen = 0 ; if ( count > 1 ) { // 如果为多包数据,需要设置分包位标志 mlen = htons( ( readlen & 0x23FF ) | 0x2000 ) ; } else { mlen = htons( readlen & 0x03FF ) ; } memcpy( &(header.msgtype), &mlen, sizeof(short) ); unsigned short downseq = seqid + i + 1 ; header.seq = htons(downseq) ; DataBuffer buf ; // 写入头部数据 buf.writeBlock( &header, sizeof(header) ) ; // 如果为分包数据需要处理分包的包数以及包序号 if ( count > 1 ) { buf.writeInt16( count ) ; buf.writeInt16( i + 1 ) ; } // 读取长度 if ( readlen > 0 ) { // 读取每个数据长度 buf.writeBlock( ptr + offset, readlen ) ; // 处理读取长度和偏移 offset += readlen ; left = left - readlen ; } buf.writeBlock( &footer, sizeof(footer) ) ; if ( Send5BData( fd , buf.getBuffer(), buf.getLength() ) ) { // 打印发送的数据 printf( " fd %d, send pic %d\n", fd->_fd, i ) ; } else { p->car_state_ = OFF_LINE ; } } p->gps_pos_ = pos ; OUT_PRINT( NULL, 0, NULL, "send pic %s", p->phone ) ; // 发送位置包 return true ; }
bool CVechileMgr::SendLocationPos( _stVechile *p , int ncount ) { if( ncount <= 0 || p == NULL ) { return false ; } time_t now = share::Util::currentTimeUsec() ; srand( now ) ; int nrand = rand() ; // 产生随机报警 DataBuffer buf ; TermLocationHeader header ; BuildHeader( header.header, 0x200 , sizeof(GpsInfo), p ) ; unsigned int alarm = 0 ; if ( now - p->last_alam_ > _alam_time && _alam_time > 0 ) { alarm = htonl( nrand ) ; p->last_alam_ = now ; } memcpy( &header.gpsinfo.alarm, &alarm, sizeof(unsigned int) ) ; unsigned int state = 0 ; memcpy( &header.gpsinfo.state , &state, sizeof(unsigned int) ) ; int pos = p->gps_pos_ ; pos = pos + 1 ; pos = pos % ncount ; Point &pt = _gps_vec[pos] ; header.gpsinfo.heigth = htons(nrand%100) ; header.gpsinfo.speed = htons(get_car_speed());//htons(nrand%1000) ; header.gpsinfo.direction = htons(nrand%360) ; // 取得当前BCD的时间 get_bcd_time( header.gpsinfo.date_time ) ; if(header.gpsinfo.speed == 0) { header.gpsinfo.state.bit6 = 0; header.gpsinfo.state.bit7 = 0; header.gpsinfo.longitude = 0 ; header.gpsinfo.latitude = 0 ; } else { header.gpsinfo.state.bit6 = 1; header.gpsinfo.state.bit7 = 1; header.gpsinfo.longitude = htonl( pt.lon ) ; header.gpsinfo.latitude = htonl( pt.lat ) ; } buf.writeBlock( &header, sizeof(header) ) ; // 需要上传CAN的数据 if ( now - p->last_candata_ > _candata_time && _candata_time > 0 ) { p->last_candata_ = now ; int index = nrand % 5; write_dword( buf, 0x01, 2000 ) ; write_word( buf, 0x02, 100 ) ; write_word( buf, 0x03, 800 ) ; if ( index != 0 ) { struct _B1{ unsigned char cmd ; unsigned int val ; }; _B1 b1 ; b1.cmd = ( index - 1 ) ; b1.val = htonl( nrand ) ; write_block( buf, 0x11, (unsigned char*)&b1 , sizeof(_B1) ) ; } else { write_byte( buf, 0x11, 0 ) ; } if ( nrand % 2 == 0 ) { struct _B2{ unsigned char type; unsigned int val ; unsigned char dir ; }; _B2 b2 ; b2.type = (( index + 1 ) % 5 ) ; b2.val = htonl( index ) ; b2.dir = ( index%2 == 0 ) ; write_block( buf, 0x12, (unsigned char*)&b2, sizeof(_B2) ) ; } if ( nrand % 3 == 0 ) { struct _B3{ unsigned int id ; unsigned short time ; unsigned char result ; }; _B3 b3 ; b3.id = htonl( index ) ; b3.time = htons( nrand % 100 ) ; b3.result = ( index % 2 == 0 ) ; write_block( buf , 0x13, (unsigned char*)&b3, sizeof(_B3) ) ; } switch( index ) { case 0: write_word( buf, 0x20, nrand ) ; write_word( buf, 0x21, nrand % 100 ) ; write_word( buf, 0x22, nrand % 1000 ) ; write_word( buf, 0x23, nrand % 80 ) ; case 1: write_dword( buf, 0x24, nrand % 157887 ) ; write_dword( buf, 0x25, nrand % 233555 ) ; write_dword( buf, 0x26, nrand % 200 ) ; write_dword( buf, 0x40, nrand % 3000 ) ; case 2: write_word( buf, 0x41, nrand % 130 ) ; write_word( buf, 0x42, nrand % 120 ) ; write_word( buf, 0x43, nrand % 200 ) ; write_word( buf, 0x44, nrand % 300 ) ; case 3: write_word( buf, 0x45, nrand % 150 ) ; write_word( buf, 0x46, nrand % 100 ) ; case 4: write_word( buf, 0x47, nrand % 150 ) ; write_word( buf, 0x48, nrand % 200 ) ; break ; } } // 长度为消息内容的长度去掉头和尾 unsigned short mlen = (buf.getLength()-sizeof(GBheader)) & 0x03FF ; buf.fillInt16( mlen, 3 ) ; GBFooter footer ; buf.writeBlock( &footer, sizeof(footer) ) ; if ( Send5BData( p->fd_, buf.getBuffer(), buf.getLength() ) ) { p->gps_pos_ = pos ; return true ; } p->car_state_ = OFF_LINE ; // 发送位置包 return false ; }
// 处理一个数据包 void CVechileMgr::HandleOnePacket( socket_t *sock, const char *data, int len ) { GBheader *header = (GBheader*)data; unsigned short _s = 0x03FF; unsigned short nmsg = 0 ; memcpy(&nmsg,&(header->msgtype),sizeof(unsigned short)); nmsg = ntohs( nmsg ) ; // 取得前10位值为长度 unsigned short msg_len = nmsg & _s; unsigned short msg_id = ntohs(header->msgid); string str_car_id = BCDtostr(header->car_id).substr(1,11); // unsigned short seq = ntohs(header->seq); const char *ip = sock->_szIp; unsigned short port = sock->_port; // 将到来的数据写入日志中 OUT_INFO( ip, port, str_car_id.c_str(), "******************fd %d on data arrrived***************", sock->_fd ); OUT_HEX( ip, port, str_car_id.c_str() , data , len ) ; OUT_INFO( ip, port, str_car_id.c_str(), "********************************************************"); int need_len = (int)(msg_len + sizeof(GBFooter) + sizeof(GBheader)) ; // 优先计算长度是否正确 if ( msg_len == 0 || len < need_len ) { OUT_ERROR( ip, port, str_car_id.c_str(), "msg id %x, data length error, len %d, msg len %d, need length %d" , msg_id, len , msg_len , need_len ) ; return ; } // 如果第13位为1则为分包消息 if ( nmsg & 0x2000 ) { // 如果为分包消息 if ( len != (int)(msg_len + sizeof(GBFooter) + sizeof(GBheader) + sizeof(MediaPart)) ){ OUT_ERROR( ip, port, str_car_id.c_str(), "msg id %x, long message data length error, len %d, msg len %d,need length %d" , msg_id, len , msg_len ,need_len + sizeof(MediaPart) ) ; return ; } } else { // 如果是普通消息 if ( len != (int)(msg_len + sizeof(GBFooter) + sizeof(GBheader)) ) { OUT_ERROR( ip, port, str_car_id.c_str(), "msg id %x, message length error, len %d, msg len %d, need length %d" , msg_id, len , msg_len , need_len ) ; return ; } } //终端注册,鉴权等与登录相关的东西,单独处理。 if ( msg_id == 0x8100 ) { TermRegisterRespHeader *resp = ( TermRegisterRespHeader *) data ; // 注册成功的响应返回鉴权码,发送鉴权处理 if ( resp->result == 0x00 ) { const int data_len = msg_len - 3 ; if ( data_len <= 0 ) { OUT_ERROR( ip, port, str_car_id.c_str(), "authcode length zero, data len: %d", data_len ) ; return ; } const char *authcode = ( const char *) ( data + sizeof(TermRegisterRespHeader) ) ; TermAuthenticationHeader req ; int nlen = sizeof(TermAuthenticationHeader) + sizeof(GBFooter) + data_len ; req.header.msgid = htons( 0x0102 ) ; req.header.seq = resp->header.seq ; memcpy( req.header.car_id , resp->header.car_id , sizeof(req.header.car_id ) ) ; unsigned short dlen = htons( data_len & 0x03FF ) ; memcpy( &req.header.msgtype , &dlen , sizeof(short) ) ; int offset = 0 ; char *buf = new char[nlen+1] ; memcpy( buf, &req, sizeof(req) ) ; offset += sizeof(req) ; // 添加返回授权码 memcpy( buf + offset, authcode , data_len ) ; offset += data_len ; GBFooter footer ; memcpy( buf + offset, &footer, sizeof(footer) ) ; if ( ! Send5BData( sock, buf, nlen ) ) { OUT_ERROR( ip, port, str_car_id.c_str(), "send term auth failed" ) ; OUT_HEX( ip, port, str_car_id.c_str(), buf, nlen ) ; } delete [] buf ; } } else if ( msg_id == 0x8001 ) { PlatFormCommonResp *resp = ( PlatFormCommonResp *) data ; unsigned short rsp_msgid = ntohs( resp->resp.resp_msg_id ) ; if ( rsp_msgid == 0x0102 ) { // 如果是终端鉴权 if ( resp->resp.result == 0x00 ) { if ( sock->_ptr != NULL ) { // 将离线用户转为在线用户 ((_stVechile*)sock->_ptr)->car_state_ = ON_LINE ; } // 记录登陆日志 OUT_CONN( ip , port, str_car_id.c_str() , "Term auth success , fd %d" , sock->_fd ) ; } } } else if (msg_id == 0x8900) //数据下行透传 { const int data_len = msg_len - 3 ; if ( data_len <= 0 ) { OUT_ERROR( ip, port, str_car_id.c_str(), "transparent transmission length zero, data len: %d", data_len ) ; return; } if (data[sizeof(TransHeader)] == 0x01){ //透传类型 DataBuffer pBuf; int nLength = _logistics->ParseTransparentMsgData((unsigned char *)&data[sizeof(TransHeader)+1], data_len-1,pBuf); if (nLength >0){ //下发返回 TermCommonResp req ; int nlen = sizeof(TermCommonResp) ; req.header.msgid = htons( 0x0001 ) ; req.header.seq = header->seq ; memcpy( req.header.car_id , header->car_id , sizeof(req.header.car_id ) ) ; unsigned short dlen = nlen - sizeof(GBheader) - sizeof(GBFooter) ; dlen = htons( dlen & 0x03FF ) ; memcpy( &req.header.msgtype , &dlen , sizeof(short) ) ; req.resp.resp_msg_id = htons( msg_id ) ; req.resp.resp_seq = header->seq ; req.resp.result = 0x00 ; // 其它统一发送通用应答 Send5BData( sock, (const char *)&req, sizeof(req)); DataBuffer repBuffer; TransHeader theader; GBFooter footer; theader.header.msgid = htons(0x0900); theader.header.seq = header->seq; unsigned short mlen = (unsigned short)pBuf.getLength(); mlen = htons( mlen & 0x03FF ) ; memcpy( &theader.header.msgtype , &mlen , sizeof(short) ) ; memcpy(theader.header.car_id,header->car_id , sizeof(req.header.car_id)); repBuffer.writeBlock(&theader,sizeof(theader)); repBuffer.writeBlock(pBuf.getBuffer(),pBuf.getLength()); repBuffer.writeBlock(&footer,sizeof(footer)); Send5BData( sock ,repBuffer.getBuffer(),repBuffer.getLength());//发送物流通用应答 } } } else { TermCommonResp req ; int nlen = sizeof(TermCommonResp) ; req.header.msgid = htons( 0x0001 ) ; req.header.seq = header->seq ; memcpy( req.header.car_id , header->car_id , sizeof(req.header.car_id ) ) ; unsigned short dlen = nlen - sizeof(GBheader) - sizeof(GBFooter) ; dlen = htons( dlen & 0x03FF ) ; memcpy( &req.header.msgtype , &dlen , sizeof(short) ) ; req.resp.resp_msg_id = htons( msg_id ) ; req.resp.resp_seq = header->seq ; req.resp.result = 0x00 ; if ( msg_id == 0x8801 ) { if ( sock->_ptr != NULL ) { OUT_PRINT( NULL, 0, NULL, "add pic %s", str_car_id.c_str() ) ; // 添加需要发送拍图片请求中 _piclist.push_back( ( _stVechile*)sock->_ptr ) ; _picmonitor.notify() ; } } // 其它统一发送通用应答 Send5BData( sock, (const char *)&req, sizeof(req) ) ; } // 记录发送数据 _bench.IncBench( BENCH_MSGRECV ) ; }
// 添加内存数据 bool CPackMgr::CMemFile::AddBuffer( DataBuffer &pack, const int index, const int count, const char *buf, int len ) { // 如果为一个数据就不需要处理组包了 if ( count == 1 ) { pack.writeBlock( buf, len ) ; return true ; } // 如果还没有开辟数据空间 if ( _vec.empty() ) { for ( int i = 0; i < count; ++ i ) { _vec.push_back( new DataBuffer ) ; } } // 如果不正确的INDEX就不处理了 if ( index > (int) _vec.size() ) { return false ; } // 取得存放数据块的内存 DataBuffer *p = _vec[index-1] ; assert( p != NULL ) ; if ( p->getLength() == 0 ) { ++ _cur ; } else { p->resetBuf() ; } p->writeBlock( buf, len ) ; // 如果接收数据包成功 if ( _cur >= (unsigned int) count ) { // 取得分包个数 int size = _vec.size() ; // 写最后一个数据包的头部 pack.writeBlock( p->getBuffer() , sizeof(GBheader) ) ; // 重新开始组包,这样数据就只有数据头和数据体 for ( int i = 0; i < size ; ++ i ) { p = _vec[i] ; if ( p->getLength() < (int)sizeof(GBheader) ){ continue ; } unsigned short mlen = p->fetchInt16( 3 ) & 0x03FF; if ( mlen > 0 ) { pack.writeBlock( p->getBuffer() + sizeof(GBheader) + 4 , mlen ) ; } } // 添加尾部数据 GBFooter footer ; pack.writeBlock( &footer, sizeof(footer) ) ; return true ; } // 更新最后一次访问的时间 _last = time(NULL) ; OUT_INFO( NULL, 0, "packmgr" , "save index file %d, current count %d total %d" , index, _cur, count ) ; return false ; }
// --------------------------------------------- void testSocket(string ip, unsigned short port) { Socket* socket = new Socket("null", 0); Socket::InetAddressPort remoteAddrAndPort; remoteAddrAndPort.port = port; Socket::getSockaddrByIpAndPort(&remoteAddrAndPort.addr, ip, port); socket->makeNonBlocking(); while (true) { bool result = socket->connect(remoteAddrAndPort); if (result) { cout << "connect success!" << endl; cm::Thread::sleep(100); char sendData[] = "TCP client request"; int numberOfBytesSent; if (SKT_SUCC == socket->send(sendData, strlen(sendData), numberOfBytesSent)) { assert(numberOfBytesSent == strlen(sendData)); cout << "send " << numberOfBytesSent << " bytes data complete" << endl; DataBuffer* response = new DataBuffer(); int numOfBytesRecved = 0; while (true) { result = socket->recv(response->getEndOfDataPointer(), response->getSize() - response->getLength(), numOfBytesRecved); assert(result != SKT_ERR); if (result == SKT_SUCC) { assert(numOfBytesRecved != 0); response->increaseDataLength(numOfBytesRecved); cout << "recv " << numOfBytesRecved << " bytes data: " << response->getData() << endl; response->reset(); break; } else { cm::Thread::sleep(1); } } } socket->close(); break; } else { cm::Thread::sleep(1); } } }