// 处理所有通用应答消息 char * PConvert::convert_lplat_r( const string &key, const string &phone, const string &val, int &len, unsigned int &msgid ) { MapString map ; // 解析数据 if ( ! parse_jkpt_value( val , map ) ) { OUT_ERROR( NULL, 0, NULL, "parse data %s failed", val.c_str() ) ; return NULL ; } char *buf = _pEnv->GetMsgCache()->GetData( key.c_str(), len ) ; if ( buf == NULL || len < (int)( sizeof(Header) + sizeof(UpPlatformMsg) ) ) { OUT_ERROR( NULL, 0, phone.c_str(), "UpPlatformMsg length %d error" , len ) ; return NULL ; } UpPlatformMsg *plat = ( UpPlatformMsg *) ( buf + sizeof(Header) ) ; unsigned int datatype = ntouv16( plat->data_type ) ; switch( datatype ) { case UP_PLATFORM_MSG_POST_QUERY_ACK: // 平台查岗 { // 修改响应处理 UpPlatformMsgPostQueryAck *resp = ( UpPlatformMsgPostQueryAck *) buf ; string value; if( ! get_map_string(map, "PLATQUERY", value)) { free_buffer(buf); return NULL; } vector<string> fields; if( ! splitvector(value, fields, "|", 4) || fields.size() != 4) { free_buffer(buf); return NULL; } CBase64 base64; base64.Decode(fields[3].c_str(), fields[3].length()); int newLen = len + base64.GetLength() + sizeof(Footer); char *newBuf = new char[newLen]; resp->header.msg_len = ntouv32(newLen); resp->up_platform_msg.data_length = ntouv32(sizeof(UpPlatformMsgpostqueryData) + base64.GetLength()); resp->up_platform_post.msg_len = ntouv32(base64.GetLength()); memcpy(newBuf, buf, len); memcpy(newBuf + len, base64.GetBuffer(), base64.GetLength()); newBuf[newLen - 1] = '\x5d'; free_buffer(buf); len = newLen; buf = newBuf; //msgid = UP_CTRL_MSG_MONITOR_VEHICLE_ACK ; msgid = ntouv32(resp->header.access_code); } break; } return buf ; }
void MsgClient::on_data_arrived( socket_t *sock, const void* data, int len) { // FUNTRACE("void ClientAccessServer::HandleInterData(int fd, const void *data, int len)"); if (len < 4) { OUT_ERROR( sock->_szIp, sock->_port, NULL, "recv data error length: %d", len ); return; } OUT_RECV( sock->_szIp, sock->_port, NULL, "on_data_arrived:[%d]%s", len, (const char*)data); CInterCoder coder; // 数据解密处理 if (!coder.Decode((const char *) data, len)) { OUT_ERROR( sock->_szIp, sock->_port, "Decode", "fd %d, MsgClient recv error data:%d,%s", sock->_fd, len, ( const char *)data ); return; } const char *ptr = (const char *) coder.Buffer(); if (strncmp(ptr, "CAIT", 4) == 0) { // 纷发处理数据 HandleInnerData( sock, ptr, coder.Length()); } else { // 处理登陆相关 HandleSession( sock, ptr, coder.Length()); } }
// 线程执行对象方法 void CScpMedia::HandleQueue( void *packet ) { MultiDesc *elem = (MultiDesc*) packet ; // mogrify -pointsize 16 -fill white -weight bolder -gravity southeast -annotate +5+5 "2012.03.03 16:59 #1" 1.jpg if ( _water_enable && elem->_type == 0 ) { // 如果打开水印且为图片时才开启水印操作 string stime = getstrtime() ; char buffer[1024] = {0}; snprintf(buffer, 1024, "%s #%d%s", stime.c_str(), elem->_channel, getEventText(elem->_event).c_str()); if ( ! picNote(elem->_path.c_str(), buffer) ) { OUT_ERROR( NULL, 0, "scpmedia", "Water %s , file path %s, water date %s failed", buffer, elem->_path.c_str(), stime.c_str() ) ; } else { OUT_PRINT( NULL, 0, "scpmedia", "Water %s, file path %s, water date %s success", buffer, elem->_path.c_str(), stime.c_str() ) ; } } // 写入远程服务器 if ( ! writeFile( elem->_abspath.c_str(), elem->_name.c_str(), elem->_path.c_str() ) ) { OUT_ERROR( NULL, 0, "scpmedia", "upload file to server failed, %s" , elem->_name.c_str() ) ; return ; } char buf[2048] = {0} ; sprintf( buf, "CAITS 0_0 %s 0 U_REPT {TYPE:3,120:%d,124:%d,121:%d,122:%d,123:%d,125:%s/%s,%s,CHANNEL_TYPE:0} \r\n", elem->_macid.c_str(), elem->_id, elem->_channel, elem->_type, elem->_ftype, elem->_event, elem->_abspath.c_str(), elem->_name.c_str() , elem->_gps.c_str() ) ; // 上传数据 _pEnv->GetMsgClient()->HandleUpData( buf, strlen(buf) ) ; }
void MsgClient::HandleInnerData( socket_t *sock, const char *data, int len) { User user = _online_user.GetUserBySocket( sock ); if (user._user_id.empty() || sock != user._fd ) { OUT_ERROR( sock->_szIp, sock->_port, "CAIS" , "find fd %d user failed, data %s", sock->_fd, data ); return; } 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; } string macid = vec[2]; // if store type need save session _session.AddSession(macid, user._user_id); // ToDo: 需要处理数据将数据递交到发布模块进行处理 _pEnv->GetPushServer()->HandleData(data, len); user._last_active_time = time(NULL); _online_user.SetUser(user._user_id, user); }
DepthRegistration *DepthRegistration::New(Method method) { if(method == DEFAULT) { #ifdef DEPTH_REG_OPENCL method = OPENCL; #elif defined DEPTH_REG_CPU method = CPU; #endif } switch(method) { case DEFAULT: OUT_ERROR("No default registration method available!"); break; case CPU: #ifdef DEPTH_REG_CPU OUT_INFO("Using CPU registration method!"); return new DepthRegistrationCPU(); #else OUT_ERROR("CPU registration method not available!"); break; #endif case OPENCL: #ifdef DEPTH_REG_OPENCL OUT_INFO("Using OpenCL registration method!"); return new DepthRegistrationOpenCL(); #else OUT_ERROR("OpenCL registration method not available!"); break; #endif } return NULL; }
// 写入远程文件 bool CScpMedia::writeFile( const char *dir, const char *name, const char *path ) { if ( ! _cfs_enable || _netobj._pobj == NULL ) return true ; int len = 0 ; char *ptr = ReadFile( path, len ) ; if ( ptr == NULL ) { OUT_ERROR( _cfs_ip.c_str(), _cfs_port, "scpmedia", "read file %s failed" , path ) ; //异常处理 return false ; } char szfile[256] = {0} ; sprintf( szfile, "%s/%s", dir, name ) ; // 这里串行化处理图片上传 share::Guard guard( _netobj._mutex ) ; #ifdef _SYN_MODE_ // 如果没有连接或者发送失败 int ret = _netobj._pobj->open( _cfs_ip.c_str(), _cfs_port, _cfs_user.c_str(), _cfs_pwd.c_str() ) ; if ( ret != FILE_RET_SUCCESS ) { OUT_ERROR( _cfs_ip.c_str(), _cfs_port, "scpmedia", "open file mgr failed, result %d" , ret ) ; FreeBuffer( ptr ) ; return false ; } #else int ret = _netobj._pobj->write( szfile, ptr, len ) ; if ( ret == FILE_RET_SUCCESS ) { FreeBuffer( ptr ) ; return true ; } // 如果没有连接或者发送失败 if ( ret == FILE_RET_NOCONN || ret == FILE_RET_SENDERR || ret == FILE_RET_READERR ) { ret = _netobj._pobj->open( _cfs_ip.c_str(), _cfs_port, _cfs_user.c_str(), _cfs_pwd.c_str() ) ; if ( ret != FILE_RET_SUCCESS ) { OUT_ERROR( _cfs_ip.c_str(), _cfs_port, "scpmedia", "open file mgr failed, result %d" , ret ) ; FreeBuffer( ptr ) ; return false ; } } #endif int retry = 0 ; // 如果发送文件失败重试几次 while( ++ retry < 3 ) { ret = _netobj._pobj->write( szfile, ptr, len ) ; if ( ret == FILE_RET_SUCCESS ) { break ; } } FreeBuffer( ptr ) ; // 返回是否写入文件成功 return ( ret == FILE_RET_SUCCESS ) ; }
//-----------------------------缓存数据处理接口----------------------------------------- // 处理外部数据 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; }
// 处理数据 bool CPlugin::Process( InterData &data , User &user ) { // if ( ! _enable ) return true ; // U_REPT 91:20,90:base64.GetBuffer() // D_SETP 91:20,90:base64.GetBuffer() CPlugUtil util ; if ( ! util.parse( data._packdata.c_str() ) ) { OUT_ERROR( NULL, 0, "Plugin", "parser kv map string %s failed", data._packdata.c_str() ) ; return false ; } int cmd = 0 ; if( ! util.getinteger( "91", cmd ) ){ OUT_ERROR( NULL, 0, "Plugin" , "get command key failed" ) ; return false ; } // 查找处理通道,如果查找失败就直接返回了,如果成功就继续下一步 CPlugWay *way = _waymgr->CheckOut( cmd , true ) ; if ( way == NULL ) { OUT_ERROR( NULL, 0, "Plugin", "get plug way failed" ) ; return false ; } string sval ; if ( ! util.getstring( "90", sval ) ) { OUT_ERROR( NULL, 0, "Plugin" , "get content data failed" ) ; _waymgr->CheckIn( way ) ; return false ; } CBase64 base ; if ( ! base.Decode( sval.c_str(), sval.length() ) ) { OUT_ERROR( NULL, 0, "Plugin" , "base64 decode failed" ) ; _waymgr->CheckIn( way ) ; return false ; } // 处理透传的命令字 cmd = cmd & 0xff ; if ( data._command == "U_REPT" ) { cmd = cmd | MSG_PLUG_IN ; // 上行数据 } else { cmd = cmd | MSG_PLUG_OUT ; // 下行数据 } // 取得对应的FD值 unsigned int fd = _fdmgr.AddUser( user._user_id.c_str(), data._macid.c_str() ) ; // 提交对应的通道进行处理数据 bool result = way->Process( fd, base.GetBuffer(), base.GetLength(), cmd , data._macid.c_str() ) ; _waymgr->CheckIn( way ) ; return result ; }
// 检测用户心跳 void PasClient::CheckUserLoop( UserSession &user ) { // 控制通道的链路维护 PccUser &tcpuser = user.GetUser( true ) ; if ( tcpuser.IsOnline() ) { if ( tcpuser.Check( 30, PCC_USER_LOOP ) && user.IsKey(true) ) { char buf[1024] = {0}; sprintf( buf, "SZ N %s\r\n", tcpuser._srv_key.c_str() ) ; SendData( tcpuser._fd, buf, strlen(buf) ) ; tcpuser.Update( PCC_USER_LOOP ) ; OUT_SEND( tcpuser._srv_ip.c_str(), tcpuser._srv_port, tcpuser._username.c_str(), "fd %d, Send TCP NOOP: %s", tcpuser._fd->_fd, buf ) ; } // 如果超时需要处理重连操作 if ( tcpuser.Check( 180, PCC_USER_ACTVIE ) ) { tcpuser.SetOffline() ; user.GetUser(false).SetOffline() ; OUT_ERROR( tcpuser._srv_ip.c_str(), tcpuser._srv_port, tcpuser._username.c_str(), "tcp actvie time timeout") ; } } else if ( ! tcpuser.IsOffline() ) { if ( tcpuser.Check( 120, PCC_USER_LOGIN ) ) { tcpuser.SetOffline() ; OUT_PRINT( tcpuser._srv_ip.c_str(), tcpuser._srv_port, tcpuser._username.c_str(), "connect server tcp timeout") ; } } // 数据通道链路维护 PccUser &udpuser = user.GetUser(false) ; if ( udpuser.IsOnline() ) { if ( udpuser.Check( 30, PCC_USER_LOOP ) && user.IsKey(false) ) { char buf[1024] = {0}; sprintf( buf, "*%s|NOOP|%s#", user.GetSrvId(), udpuser._srv_key.c_str() ) ; SendData( udpuser._fd, buf, strlen(buf) ) ; // _udp_handle.deliver_data( udpuser._fd, udpuser._srv_ip.c_str(), udpuser._srv_port, buf, strlen(buf) ) ; udpuser.Update( PCC_USER_LOOP ) ; OUT_SEND( udpuser._srv_ip.c_str(), udpuser._srv_port, udpuser._username.c_str(), "fd %d, Send UDP NOOP: %s", udpuser._fd->_fd, buf ) ; } // 如果UDP心跳没有应答就直接处理重连了 if ( udpuser.Check(180, PCC_USER_ACTVIE) ) { udpuser.SetOffline() ; OUT_ERROR( udpuser._srv_ip.c_str(), udpuser._srv_port, udpuser._username.c_str(), "udp active time timeout" ) ; tcpuser.SetOffline() ; } } else { if ( udpuser.Check( 120, PCC_USER_LOGIN) ) { udpuser.SetOffline() ; OUT_PRINT( udpuser._srv_ip.c_str(), udpuser._srv_port, udpuser._username.c_str(), "connect server udp timeout") ; tcpuser.SetOffline() ; } } }
// 添加到数据包对象 bool CPackMgr::AddPack( DataBuffer &pack, const char *carid, const int msgid, const int index, const int count, const int seq, const char *buf, int len ) { share::Guard g( _mutex ) ; { if ( count <= 0 || index <= 0 ) { OUT_ERROR( NULL, 0, "packmgr" , "msg id %x, add pack car id %s, count %d, index %d error" , msgid, carid, count, index ) ; return false ; } char key[1024] = {0} ; // 这里ID是由手机号以及消息ID和分包数 sprintf( key, "%s-%d-%d-%d" , carid, msgid, count , (seq-index)+1 ) ; CMemFile *p = NULL ; CMapFile::iterator it = _mapPack.find( key ) ; if ( it == _mapPack.end() ) { p = new CMemFile(key) ; if ( p == NULL ) { OUT_ERROR( NULL, 0, "packmgr" , "msg id %x, add pack car id %s, count %d, index %d malloc data faild" , msgid, carid, count, index ) ; return false ; } } else { p = it->second ; // 移除不必要时间索引 p = _queue.erase( p ) ; } // 如果成功将多个数据合成一个数据包则直接从内存删除 if ( p->AddBuffer( pack, index, count, buf, len ) ) { // 打印数据信息 OUT_INFO( NULL, 0, "packmgr" , "msg id %x, build msg pack success", msgid ) ; // 只有不为一个数据长消息才会有索引 if ( it != _mapPack.end() ) { // 从队列中移除 _mapPack.erase( it ) ; } delete p ; return true ; } // 只有第一次添加时才添加到队列中 if ( it == _mapPack.end() ) { _mapPack.insert( pair<string,CMemFile*>( key, p ) ) ; } // 添加时间索引 _queue.push( p ) ; return false ; } }
// 处理下载的后的图片数据 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 ) ; }
// 取得头数据 bool PConvert::get_map_header( const std::string ¶m, MapString &val, int &ntype ) { if ( ! parse_jkpt_value( param, val ) ) { OUT_ERROR( NULL, 0, NULL, "parse data %s failed", param.c_str() ) ; return false ; } if ( ! get_map_integer( val, "TYPE", ntype ) ) { OUT_ERROR( NULL, 0, NULL, "get data %s type failed", param.c_str() ) ; return false ; } 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); }
// 更新操作 bool COracleDB::Update( const char *stable, const CSqlObj *obj, const CSqlWhere *where ) { string supdate; // 构建更新操作 if ( ! BuildUpdate( ( OracleSqlObj* ) obj, supdate ) ) { return false; } string sql = "update "; sql += stable; sql += " set "; sql += supdate; string swhere; // 构建的条件 if ( BuildWhere( where, swhere ) ) { sql += " where "; sql += swhere; } // 执行更新操作 int ret = oracle_exec( sql.c_str(), true ) ; if ( ret != DB_ERR_SUCCESS ) { OUT_ERROR( NULL, 0, "Oracle", "Exceute sql: %s, result %d", sql.c_str() , ret ); return false; } return true; }
/** * Prepare socket address based on hostname:port. * Call DNS lookup of the hostname. * @author Petr Djakow */ int Utils::prepareSocketAddr( struct sockaddr_in *addr, const char * hostname, const unsigned short port) { addr->sin_family = AF_INET; addr->sin_port = htons(port); //network byte order if(hostname == NULL) { //everyone is able to connect to server addr->sin_addr.s_addr = INADDR_ANY; } else { struct hostent *he; if( (he = gethostbyname(hostname)) == NULL ) { OUT_ERROR(("host '%s' not found\n", hostname)); return -1; //error } assert(he->h_addrtype == AF_INET); assert(he->h_length == sizeof(addr->sin_addr.s_addr)); memcpy(&addr->sin_addr.s_addr, he->h_addr_list[0], (size_t)he->h_length); } return 0; //success }
// 向MSG上传消息 bool MsgClient::Deliver( const char *data, int len ) { // 如果没有开启节点服务就直接发送了 vector<User> vec = _online_user.GetOnlineUsers() ; if ( vec.empty() ) { OUT_ERROR( NULL, 0, "msg", "HandleUpMsgData %s", data ) ; return false ; } int send = 0 ; for ( int i = 0; i < (int) vec.size(); ++ i ) { User &user = vec[i] ; if ( user._fd == NULL ) continue ; if ( SendData( user._fd, data, len ) ) { ++ send ; } } if ( send > 0 ) { OUT_PRINT( NULL , 0, "msg", "HandleUpMsgData %s", data ); } return true ; }
bool MsgClient::SendDataToUser( const string &area_code, const char *data, int len) { if ( area_code == SEND_ALL ) { vector<User> users = _online_user.GetOnlineUsers() ; if ( users.empty() ) { return false ; } for ( size_t i = 0; i < users.size(); ++ i ) { // 群发数据 SendData( users[i]._fd, data, len ) ; } return true ; } char buf[512] = {0}; sprintf( buf, "%s%s", MSG_USER_TAG, area_code.c_str() ) ; User user = _online_user.GetUserByUserId( buf ); if( user._user_id.empty() || user._user_state != User::ON_LINE ) { OUT_ERROR( user._ip.c_str() , user._port , buf , "SendDataToUser %s failed" , data ) ; return false; } // 发送数据重新添加循环码的处理 return SendData( user._fd, data, len ) ; }
bool PasClient::HandleData( const char *data, int len ) { PccUser &user = _user.GetUser( false ) ; // 发送数据到监管平台,这里是通过数据通道来发送数据 if ( ! _user.IsOnline(false) ) { OUT_ERROR( user._srv_ip.c_str(), user._srv_port, user._username.c_str(), "User data way is not exist, data: %s" , data ) ; // _user.SetState( false, true ) ; return false; } if ( ! SendData( user._fd, data, len ) ){ OUT_ERROR( user._srv_ip.c_str(), user._srv_port, user._username.c_str(), "Send Data Failed,%s" , data ) ; return false ; } OUT_PRINT( user._srv_ip.c_str(), user._srv_port, user._username.c_str(), "fd %d, Send Data: %s" , user._fd->_fd, data ) ; return true ; }
void PasServer::HandleOfflineUsers() { vector<User> vec_users = _online_user.GetOfflineUsers(3 * 60); for (int i = 0; i < (int) vec_users.size(); i++) { User user = vec_users[i]; if (user._socket_type == User::TcpClient) { // 移除统计功能的用户 _datastat.Remove(user._access_code); if (user._fd != NULL) { OUT_WARNING( user._ip.c_str(), user._port, user._user_id.c_str(), "HandleOfflineUsers close socket fd %d", user._fd->_fd); CloseSocket(user._fd); } } else if (user._socket_type == User::TcpConnClient) { if (user._fd != NULL) { OUT_WARNING( user._ip.c_str(), user._port, user._user_id.c_str(), "TcpConnClient close socket fd %d", user._fd->_fd); // user.show(); CloseSocket(user._fd); user._fd = NULL; } if (ConnectServer(user, 3)) { //连接成功,重新加到在线列表当中。 if (!_online_user.AddUser(user._user_id, user)) _online_user.SetUser(user._user_id, user); } else if (user._connect_info.keep_alive == AlwaysReConn || user._connect_info.reconnect_times > 0) { _online_user.AddUser(user._user_id, user); } else { if (user._connect_info.reconnect_times <= 0) { // 如果用户是下级平台,应该向下级平台发送从链路断开消息 DownDisconnectInform msg; msg.header.msg_len = ntouv32(sizeof(DownDisconnectInform)); msg.header.access_code = ntouv32(user._access_code); msg.header.msg_seq = ntouv32(_proto_parse.get_next_seq()); msg.header.msg_type = ntouv16(DOWN_DISCONNECT_INFORM); msg.error_code = 0x0; // 原因:从链路断开 char buf[200]; sprintf(buf, "U_%u", user._access_code); // 取主链路fd User main_user = _online_user.GetUserByUserId(buf); if (!main_user._user_id.empty()) { if (SendCrcData(main_user._fd, (const char*) &msg, sizeof(msg))) { OUT_INFO( main_user._ip.c_str(), main_user._port, "pas", "DOWN_DISCONNECT_INFORM"); } else { OUT_ERROR( main_user._ip.c_str(), main_user._port, "pas", "DOWN_DISCONNECT_INFORM"); } } } } } } }
// 客户对内纷发数据 void PasServer::HandleClientData(const char *data, const int len) { if (len < (int) sizeof(Header) + (int) sizeof(Footer)) { OUT_ERROR( NULL, 0, NULL, "PasServer::HandleCasDownData packet len %d error", len); return; } Header *header = (Header *) data; unsigned int access_code = ntouv32(header->access_code); string str_access_code = uitodecstr(access_code); unsigned int msg_len = ntouv32(header->msg_len); if (msg_len != (unsigned int) len) { OUT_ERROR( NULL, 0, str_access_code.c_str(), "PasServer::HandleCasDownData packet len %d, msg length %d error", len, msg_len); return; } // 针对平台查岗类消息广播给所有平台 if (ntouv16(header->msg_type) == DOWN_PLATFORM_MSG) { // 下发给所有平台 vector<User> vec = _online_user.GetOnlineUsers(); int size = vec.size(); for (int i = 0; i < size; ++i) { User &user = vec[i]; if (user._user_id.at(0) == 'U') { SendDataToPasUser(user._access_code, data, len); } } } else { // 通过WEB平台下发过来也需要记录对应接入码情况 string mac_id = _proto_parse.GetMacId( data, len ); if (!mac_id.empty()) { // 记录车号对应用接入码关系 access_code = _corp_info_handler.get_access_code( mac_id ) ; } string info = _proto_parse.Decoder( data, len ); if (SendDataToPasUser(access_code, data, len )) { OUT_SEND( NULL, 0, str_access_code.c_str(), "CAS:%s", info.c_str()); } else { OUT_ERROR( NULL, 0, str_access_code.c_str(), "CAS:%s", info.c_str()); } } }
bool MsgClient::Start( void ) { if ( ! _httpcaller.Start() ) { OUT_ERROR( NULL, 0, NULL, "start http caller failed" ) ; return false ; } return StartClient( "0.0.0.0", 0, 3 ) ; }
// 初始化插件通道 bool CCarService::Start( void ) { if ( ! _srvCaller->Start() ){ OUT_ERROR( NULL, 0, "CCarService", "start service caller http failed" ) ; return false ; } return true ; }
// 处理HTTP的响应回调处理 void MsgClient::ProcessResp( unsigned int seqid, const char *data, const int len , const int err ) { // 处理数据 if ( data == NULL || err != HTTP_CALL_SUCCESS || len == 0 ) { OUT_ERROR( NULL, 0, "Pic" , "pic seqid %u, error %d" , seqid, err ) ; return ; } _convert->sendpicture( seqid, data, len ) ; }
// 发送数据进行5B编码处理 bool PasServer::Send5BCodeData(socket_t *sock, const char *data, int len) { C5BCoder coder; if (!coder.Encode(data, len)) { OUT_ERROR( sock->_szIp, sock->_port, NULL, "Send5BCodeData failed , socket fd %d", sock->_fd ); return false; } return SendData(sock, coder.GetData(), coder.GetSize()); }
bool MsgClient::Start( void ) { // 初始化两个HTTP对象 if ( ! _httpCall.Start() ) { OUT_ERROR( NULL, 0, NULL, "start http caller failed") ; return false ; } return StartClient( "0.0.0.0", 0, 4 ) ; }
bool CSynServer::Init(ISystemEnv *pEnv) { _pEnv = pEnv; char szip[128] = {0} ; if ( ! pEnv->GetString( "db_ip", szip ) ) { OUT_ERROR( NULL, 0, NULL, "get database ip failed" ) ; return false ; } char szport[128] = {0} ; if ( ! pEnv->GetString( "db_port", szport ) ) { OUT_ERROR( NULL, 0, NULL, "get database port failed" ) ; return false ; } char szuser[128] = {0} ; if ( ! pEnv->GetString( "db_user", szuser ) ) { OUT_ERROR( NULL, 0, NULL, "get database user failed" ) ; return false ; } char szpwd[128] = {0} ; if ( ! pEnv->GetString( "db_pwd", szpwd ) ) { OUT_ERROR( NULL, 0, NULL, "get database pwd failed" ) ; return false ; } char szdb[128] = {0} ; if ( ! pEnv->GetString( "db_name", szdb ) ) { OUT_ERROR( NULL, 0 , NULL, "get database name failed" ) ; return false ; } sprintf( _szdb, "type=oracle;ip=%s;port=%s;user=%s;pwd=%s;db=%s", szip, szport, szuser, szpwd, szdb ) ; int nvalue = 0 ; // 处理同步方式 if ( pEnv->GetInteger( "syn_mode", nvalue ) ) { _synmode = nvalue ; } // 取得需要同步更新的时间 if ( pEnv->GetInteger( "syn_time", nvalue ) ) { _syntime = nvalue ; } if ( ! _thpool.init( 1, NULL, this ) ) { OUT_ERROR( NULL, 0, NULL , "init syn thread failed" ) ; return false ; } _inited = true ; if ( ! _dbpool->Init() ) { OUT_ERROR( NULL, 0, NULL, "init database pool failed" ) ; return false ; } return true ; }
/** * Try to close filedescriptor > 2. * @author Petr Djakow */ void Utils::closefd(int sockfd) { assert(sockfd > 2); if( close(sockfd) == -1 ) { OUT_ERROR(("close(%d)", sockfd)); return; } OUT_DEBUG(("Filedescriptor #%d closed", sockfd)); }
bool CSynServer::Start(void) { _thpool.start() ; if ( ! _dbpool->Start() ){ OUT_ERROR( NULL, 0, NULL, "start database pool failed" ) ; return false ; } return true ; }
// 需要初始化对象 bool CCarService::Init( IPlugin *plug , const char *url, int sendthread , int recvthread , int queuesize ) { _pCaller = plug ; if ( ! _srvCaller->Init( plug , url, sendthread, recvthread , queuesize ) ) { OUT_ERROR( NULL, 0, "CCarService", "init service caller http failed" ) ; return false ; } return true ; }