// 处理数据 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 CPlugin::OnDeliver( unsigned int fd, const char *data, int len , unsigned int cmd ) { string userid, macid ; if ( ! _fdmgr.GetUser( fd, userid, macid ) ) { OUT_ERROR( NULL, 0, "Plugin", "get fd %u user failed", fd ) ; return ; } CBase64 base ; base.Encode( data, len ) ; char scmd[512] = {0}; sprintf( scmd, "CAITS 0_%u %s 0 D_SETP {TYPE:9,91:%d,90:", fd, macid.c_str(), ( 0xff & cmd ) ) ; string sdata = scmd ; sdata += base.GetBuffer() ; sdata += "} \r\n" ; // 发送数据出去 if ( ! _pEnv->GetMsgClientServer()->DeliverEx( userid.c_str(), sdata.c_str(), sdata.length() ) ) { _fdmgr.DelUser( fd ) ; } }
// 转换监管协议 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 ; }
// 转换监管协议 char * PConvert::convert_lplat( 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 type ; if ( ! get_map_string( map , "TYPE", type ) || type != "D_INFO") { OUT_ERROR( NULL, 0, NULL, "get data %s type failed", val.c_str() ) ; return NULL ; } string text; if (!get_map_string(map, "TEXT", text) || text.empty()) { OUT_ERROR( NULL, 0, NULL, "get data %s type failed", val.c_str() ); return NULL; } vector<string> fields; if (Utils::splitStr(text, fields, '|') != 2) { OUT_ERROR( NULL, 0, NULL, "%s, inner msg invalid", val.c_str() ); return NULL; } unsigned short msgid_master = 0x1600; unsigned short msgid_slave= 0; if(fields[0] == "COMPANY") { msgid_slave = 0x1605; } else if(fields[0] == "VEHICLE") { msgid_slave = 0x1606; } else if(fields[0] == "PERSON") { msgid_slave = 0x1607; } CBase64 base; if(!base.Decode(fields[1].c_str(), fields[1].length())) { OUT_ERROR( NULL, 0, NULL, "%s, inner msg invalid", val.c_str() ); return NULL; } len = sizeof(UpbaseMsgVehicleAddedAck) + base.GetLength() + sizeof(Footer); char *buf = new char[len]; UpbaseMsgVehicleAddedAck addedAck; Footer footer; addedAck.header.msg_len = htonl(len); addedAck.header.msg_seq = htonl(_seq_gen.get_next_seq()); addedAck.header.msg_type = htons(msgid_master); addedAck.msg_header.data_type = htons(msgid_slave); addedAck.msg_header.data_length = htonl(base.GetLength()); int pos = 0; memcpy(buf + pos, &addedAck, sizeof(UpbaseMsgVehicleAddedAck)); pos += sizeof(UpbaseMsgVehicleAddedAck); memcpy(buf + pos, base.GetBuffer(), base.GetLength()); pos += base.GetLength(); memcpy(buf + pos, &footer, sizeof(Footer)); return buf ; }