新版天线库

2019-07-14 11:18发布

首先看libgbdsrc/src中的dbdsrc.c文件   _gbdsrc_thread_func 开头函数 完成了用函数_connect_rsu连接天线,并且使用select 监听套接字 ,当接受到包时,使用trans_obj.c的函数gbdsrc_recv接收,然后调用protocol.c 中的gbdsrc_protocol_process 开始对接受到的包进行分析。    pkg_size = _package_decode(buf + 2, &pkg_p, buf_len - 4);  去掉包头的STX和包尾的BCC和ETX      然后流程如下: 1.先看如果是b2  b3 b4 指令,如果pkg[6]errorcode == 0x08 发送c2停止交易的指令 2.如果是b0(设备状态信息帧) 忽略 3如果是b1  (地感状态信息帧) 则会送c1指令 4 如果是b2 (vst)     memcpy(&v, pkg + 2, 4);     if (v == 0) {         _gbdsrc_send_c2_package(svc, pkg[0]); break;     }     如果如法获取OBUID号,则发送c2指令        if ((pkg[32] >> 7) != 0) {       _gbdsrc_send_c2_package(svc, pkg[0]);       gbdsrc_on_trans_failed(svc, ERR_NO_ICCARD, ERR_NO_ICCARD_STR);       break;     } 如果通过判断OBUID发现无IC卡存在,发送c2指令     当pkg[6] errorcode ==0 时,记录 obuID 和obu状态 然后发送c1指令   5 如果是B3 (OBU信息帧) 判断svc->obu_id中存储的OBUID和B3信息帧中存储的ID是否相同,如果不同则发送C2指令 如果相同的话则首先查询黑名单,如果此OBUID在黑名单中,则终止交易,发送C1指令 如果此OBU正常则发送c1指令,并记录OBU记载的车牌号到svc->veh_num中 记录OBU存储的车辆类型到svc->veh_type 中   6 如果是B4 IC卡信息帧 先验证errorcode   然后是一个数据结构        typedef struct {     lane_type_t lane_type;     trans_type_t trans_type;       /* 交易开始和终止时间 */     struct timeval trans_begin;     struct timeval trans_end;       time_t last_trans_time;     unsigned char psam[6]; /* PSAM卡号 */     unsigned int obu_id; /* OBU序列号 */     char veh_num[12]; /* 车牌号码 */     char card_veh_num[12]; /* 卡内车牌号码 */     unsigned int veh_type; /* 车型 */     unsigned int card_balance; /* 交易后余额 */     time_t valid_begin_time; /* 启用日期 */     time_t valid_end_time; /* 到期日期 */     unsigned int TAC; /* TAC认证码 */     unsigned short card_trans_count; /* 卡交易计数 */     unsigned int psam_trans_count; /* PSAM交易计数 */       char msg[128];       trans_object_destroy_func_t destroy;     trans_object_duplicate_func_t duplicate;   } trans_head_t;     if (svc->trans) trans_bak = svc->trans;   //如果svc中目前存在一个交易 则把目前的交易情况用trans_bak 保存下来??   svc->trans = gbdsrc_trans_object_new(svc, pkg[7]);  //通过卡类型分配新的trans         void * gbdsrc_trans_object_new(gbdsrc_svc_t *svc, unsigned char card_type) {   void *result;   trans_head_t *head;     result = NULL;   head = NULL;   if (card_type == 0) { // 此卡是国标cpu卡     if (svc->cfg.lane_type == LANE_ENTRY) { //是进站口       result = malloc(sizeof(gb_entry_trans_t));       assert(result != NULL);         memset(result, 0, sizeof(gb_entry_trans_t));       head = &((gb_entry_trans_t *)result)->head;       head->trans_type = TRANS_GB_ENTRY; //国标 进站     }     else {       result = malloc(sizeof(gb_exit_trans_t));//出站       assert(result != NULL);         memset(result, 0, sizeof(gb_exit_trans_t));       head = &((gb_exit_trans_t *)result)->head;       head->trans_type = TRANS_GB_EXIT; //国标出站     }   }   else if (card_type == 1) {//北京市政一卡通     result = malloc(sizeof(bmac_trans_t));     assert(result != NULL);       memset(result, 0, sizeof(bmac_trans_t));     head = &((bmac_trans_t *)result)->head;     head->trans_type = TRANS_BMAC;   }     if (head) {     head->lane_type = svc->cfg.lane_type;     head->destroy = free;     head->duplicate = _gbdsrc_trans_object_duplicate;   }     return result; }                   head = (trans_head_t *)svc->trans;       head->trans_begin = svc->trans_begin;       head->obu_id = svc->obu_id;       head->veh_type = svc->veh_type;       memcpy(head->veh_num, svc->veh_num, sizeof(head->veh_num));  对trans的交易开始时间,obuid,卡类型,OBU中记载的车牌号进行赋值    _gbdsrc_get_ic_info(svc, pkg);  从B4包中获取IC卡信息   首先获得IC卡内余额  memcpy(&head->card_balance, buf + 10, 4);   如果是一卡通车辆,暂时不做处理    memcpy(&card_net_no, buf + 28, 2);  获得卡片网络编号  user_type = buf[58];    获得用户类型 memcpy(&head->card_veh_num, buf + 46, 12);  获得卡内存储的车牌号  memcpy(&head->valid_begin_time, buf + 38, 4);  获得启用日期    memcpy(&head->valid_end_time, buf + 42, 4);  获得到期日期     if (head->trans_type == TRANS_GB_ENTRY) {  如果交易类型是入口的话    trans->card_type = buf[26];  获得卡片类型     if (trans->card_type == 22)   22ETC储值卡  卡片类型是ETC储值卡   offset = 3;    如果是ETC储值卡,则偏移量是3 则读取0019文件       else offset = 0;     不是ETC储值卡,则偏移量是0,则读取0012文件   然后上次(交易的时间,入口站网络编号,入口站号,入口收费员编号)赋值给tran           /* 卡片网络编码 */       trans->card_net_no = card_net_no;         /* 卡号 */       memcpy(trans->card_no, buf + 30, 8);         /* 入口车道号 */       trans->entry_lane_id = buf[offset + 65];         /* 入口班次 */       trans->entry_job_order = buf[offset + 84];         /* 入出口状态 */       trans->trans_state = buf[offset + 71];             if (trans->card_type == 23)  ETC记账卡 trans->head.card_balance = 0;     else if (head->trans_type == TRANS_GB_EXIT) {如果是出口 和上一步一样,得到各种信息,然后写道trans结构中     /* 出口重取账单 */  /* 判断上一次交易是否为同一OBU,并且入口站号为本站则发送CA取B5 */   _gbdsrc_process_b4(svc, pkg[0]);  //然后处理B4       /* 黑名单OBU */   if (gbdsrc_obu_blacklist_query(svc, head->obu_id) == 1) {     _gbdsrc_send_c2_package(svc, rs_ctl);//c2终止交易指令     gbdsrc_on_trans_failed(svc, ERR_OBU_BLACKLIST, ERR_OBU_BLACKLIST_STR);     return;   }       一卡通不以处理   以下是国标卡的处理流程     if (head->trans_type == TRANS_GB_EXIT) {     gb_exit_trans_t *trans = svc->trans;       memcpy(card_no, trans->card_no, 8);     card_type = trans->card_type;     trans_state = trans->trans_state;     user_type = trans->user_type;   }   else {     gb_entry_trans_t *trans = svc->trans;       memcpy(card_no, trans->card_no, 8);     card_type = trans->card_type;     trans_state = trans->trans_state;     user_type = trans->user_type;   }         /* 判断是否为黑名单卡 */  /* 启用日期判断 */  /* 到期日期判断 */ /* 判断车卡绑定 */  /* 公务卡判断 */    if (head->trans_type == TRANS_GB_EXIT) {   则如果是公务卡 则 _gbdsrc_send_c6_package(svc, rs_ctl);  /* 出口判断入口信息 */  /* check last transaction time */    /* 超时判断 */           trans->trans_amount = gbdsrc_toll_rate_query(svc, trans->entry_gate_id,trans->head.veh_type);           /* 无效入口 */     if (trans->trans_amount == -1) {       _gbdsrc_send_c2_package(svc, rs_ctl);       gbdsrc_on_trans_failed(svc, ERR_INVALID_ENTRY, ERR_INVALID_ENTRY_STR);       return;     }   /* 余额不足 */       if ((trans->trans_amount > trans->balance_before_trans) && (card_type == 22)) {       _gbdsrc_send_c2_package(svc, rs_ctl);       gbdsrc_on_trans_failed(svc, ERR_BALANCE_NOT_ENOUGH,     ERR_BALANCE_NOT_ENOUGH_STR);       return;     }      _gbdsrc_send_c6_package(svc, rs_ctl);     如果是入口       trans->entry_net_no = svc->cfg.net_no;     trans->entry_gate_id = svc->cfg.toll_gate_id;     trans->entry_lane_id = svc->cfg.lane_id;     trans->entry_job_num = svc->job_num;     trans->entry_job_order = svc->job_order;     trans->trans_state = 0x03; /* 封闭ETC入 */       _gbdsrc_send_c3_package(svc, rs_ctl);  //c3是传统交易       如果是B5指令         if (pkg[6] == 0) {       _gbdsrc_get_trans_info(svc, pkg);       gbdsrc_on_trans_complete(svc);       _gbdsrc_send_c1_package(svc, pkg[0]);     }     else {       trans_head_t *head = (trans_head_t *)svc->trans;       if (head) { (*head->destroy)(svc->trans); svc->trans = NULL;       }       _gbdsrc_send_c2_package(svc, pkg[0]);     }       break;