/** * @brief 终端参数F7操作(终端IP地址和端口) */ int ParaOperationF7(int flag, unsigned short metpid, unsigned char *buf, int len, int *actlen) { int alen; int lenusr, lenpwd; unsigned char *pbuf; if(0 == flag) { lenusr = strlen(ParaTerm.termip.username); lenpwd = strlen(ParaTerm.termip.pwd); alen = 24 + lenusr + lenpwd; if(alen > len) return POERR_FATAL; *actlen = alen; pbuf = buf; smallcpy(pbuf, ParaTerm.termip.ipterm, 12); pbuf += 12; *pbuf++ = ParaTerm.termip.proxy_type; smallcpy(pbuf, ParaTerm.termip.ipproxy, 4); pbuf += 4; *pbuf++ = (unsigned char)ParaTerm.termip.portproxy; *pbuf++ = (unsigned char)(ParaTerm.termip.portproxy >> 8); *pbuf++ = ParaTerm.termip.proxy_connect; *pbuf++ = lenusr; if(lenusr) strcpy((char *)pbuf, ParaTerm.termip.username); pbuf += lenusr; *pbuf++ = lenpwd; if(lenpwd) strcpy((char *)pbuf, ParaTerm.termip.pwd); pbuf += lenpwd; pbuf[0] = ParaTerm.termip.portlisten; pbuf[1] = ParaTerm.termip.portlisten >> 8; }
/** * @brief 终端参数F1操作(终端上行通信口通信参数设置) * @param flag 操作方式, 0-读, 1-写 * @param metpid 测量点号 * @param buf 缓存区指针 * @param len 缓存区长度 * @param actlen 有效数据长度(由函数返回) * @return 0成功, 否则失败(参看POERR_XXX宏定义) * @note 以下同类参数和返回值相同, 不做重复注释 */ int ParaOperationF1(int flag, unsigned short metpid, unsigned char *buf, int len, int *actlen) { if(0 == flag) smallcpy(buf, &ParaTerm.tcom.rts, 6); else{ smallcpy(&ParaTerm.tcom.rts, buf, 6); SaveParaTerm(); } return 0; }
/** * @brief 终端参数F6操作(终端组地址设置) */ int ParaOperationF6(int flag, unsigned short metpid, unsigned char *buf, int len, int *actlen) { if(0 == flag) smallcpy(buf, ParaTerm.grpaddr.addr, 16); else { smallcpy(ParaTerm.grpaddr.addr, buf, 16); SaveParaTerm(); } return 0; }
/** * @brief 终端参数F5操作(终端上行通信消息认证参数设置) */ int ParaOperationF5(int flag, unsigned short metpid, unsigned char *buf, int len, int *actlen) { if(0 == flag) smallcpy(buf, &ParaTerm.pwd.art, 3); else { smallcpy(&ParaTerm.pwd.art, buf, 3); SaveParaTerm(); } return 0; }
/** * @brief 终端参数F4操作(主站电话号码和短信中心号码) */ int ParaOperationF4(int flag, unsigned short metpid, unsigned char *buf, int len, int *actlen) { if(0 == flag) smallcpy(buf, ParaTerm.smsc.phone, 16); else { smallcpy(ParaTerm.smsc.phone, buf, 16); SaveParaTerm(); } return 0; }
/** * @brief 终端参数F3操作(主站IP地址和端口) */ int ParaOperationF3(int flag, unsigned short metpid, unsigned char *buf, int len, int *actlen) { if(0 == flag) smallcpy(buf, ParaTerm.svrip.ipmain, 28); else { smallcpy(ParaTerm.svrip.ipmain, buf, 28); ParaTerm.svrip.apn[16] = 0; SaveParaTerm(); } return 0; }
static void PlRscStdMakeDest(struct amr_module_t *pmodule, plc_dest_t *dest) { unsigned char proto; unsigned char *pdata; memset((unsigned char *)dest, 0, sizeof(plc_dest_t)); pdata = pmodule->app_send_buf; proto = pdata[8]; proto &= 0x1f; if(proto & 0x10) { if(proto == 0x10) proto = 1; else proto = 2; } else if(proto == 0x08) proto = 2; else proto = 1; smallcpy(dest->dest, pdata+1, 6); dest->src[0] = pmodule->module_id[0]; dest->src[1] = pmodule->module_id[1]; dest->src[2] = pmodule->module_id[2]; dest->src[3] = pmodule->module_id[3]; dest->src[4] = pmodule->module_id[4]; dest->src[5] = pmodule->module_id[5]; dest->metid = pmodule->cur_metid+1; dest->portcfg = pmodule->port; dest->proto = proto; dest->route.level = 0; dest->route.phase = 0; }
static void PltReadMet(unsigned short metid) { plc_dest_t dest; unsigned char databuf[4]; unsigned short mid = metid - PLC_BASEMETP; PrintLog(LOGTYPE_DOWNLINK, "read met%d ...\n", metid); if(0 == CycCount) ReadMetsCount1++; MakePlcDest(metid, &dest); if(PlcRead(&dest, 0x9010, databuf, 4) > 0) { DebugPrint(LOGTYPE_DOWNLINK, "9010=%02X%02X%02X.%02X\n", databuf[3], databuf[2], databuf[1], databuf[0]); PltFileData.prd[PrdCurrent].mets[mid].sec = PlcState[metid].oktime.second; PltFileData.prd[PrdCurrent].mets[mid].min = PlcState[metid].oktime.minute; PltFileData.prd[PrdCurrent].mets[mid].hour = PlcState[metid].oktime.hour; PltFileData.prd[PrdCurrent].mets[mid].routes = PlcState[metid].routes & 0x0f; PltFileData.prd[PrdCurrent].mets[mid].routes |= (PlcState[metid].quality<<4) & 0xf0; smallcpy(PltFileData.prd[PrdCurrent].mets[mid].ene, databuf, 4); OkMetsCount++; if(0 == CycCount) OkMetsCount1++; } }
static int PlRscStdReadData(struct amr_module_t *pmodule, rep_reading_info *preadinginfo) { plc3762_pkt_t *pkt = (plc3762_pkt_t *)pmodule->link_send_buf; plc3762_pkt_t *prcv = (plc3762_pkt_t *)pmodule->link_recv_buf; plc_dest_t dest; unsigned char *pdata; int i, applen; PlRscStdMakeDest(pmodule, &dest); pdata = pmodule->app_send_buf; pkt->afn = PL3762_AFN_FORWARD; FN_DT(1, pkt->dt); pkt->data[0] = dest.proto; pkt->data[1] = (unsigned char)(pmodule->app_sendlen); memcpy(pkt->data+2, pdata, pmodule->app_sendlen); pkt->len = pmodule->app_sendlen + 2; pkt->ctrl = 0x41; if(Pl3762SendPkt(pmodule, &dest, 0)) goto mark_fail; if(PlRsc3762RecvPktTimeout(pmodule, PL3762_AFN_FORWARD, 1, PLRSC_READMET_TIMEOUT)) goto mark_fail; for(i=0; i<6; i++) { if(pmodule->link_recv_dest.src[i] != dest.dest[i]) goto mark_fail; } if(prcv->data[0] != dest.proto) goto mark_fail; if(prcv->len != (prcv->data[1]+2)) goto mark_fail; applen = prcv->data[1] & 0xff; if(applen <= 0) goto mark_fail; //去掉FE pdata = prcv->data + 2; for(i=0; i<applen; i++) { if(0x68 == pdata[i]) break; } if((i+8) >= applen) goto mark_fail; Pl3762GetReadingInfo(pmodule, preadinginfo); smallcpy(pmodule->app_recv_buf, pdata+i, applen-i); pmodule->app_proto = dest.proto; pmodule->app_recvlen = applen-i; return pmodule->app_recvlen; mark_fail: return PLCERR_INVALID; }
void UpdatePlMdb(unsigned short mid, unsigned short itemid, const unsigned char *buf, int len) { if(mid < PLC_BASEMETP || mid >= MAX_METER) return; mid -= PLC_BASEMETP; switch(itemid) { case 0x9010: case 0x9210: smallcpy(PlMdbDay[mid].meter_ene, buf, 4); PlMdbDay[mid].readtime = ClockToReadTime(&PlcState[mid+PLC_BASEMETP].oktime, 0); /*smallcpy(PlMdbMonth[mid].ene, buf, 4); PlMdbMonth[mid].readtime = ClockToReadTime(&PlcState[mid+PLC_BASEMETP].oktime, 1);*/ FlagDaySaved = 0; //FlagMonthSaved = 0; break; case 0x9410: smallcpy(PlMdbMonth[mid].ene, buf, 4); FlagMonthSaved = 0; PlMdbMonth[mid].readtime = ClockToReadTime(&PlcState[mid+PLC_BASEMETP].oktime, 1); break; //case 0x9011: case 0x9411: smallcpy(PlMdbMonth[mid].ene+4, buf, 4); FlagMonthSaved = 0; //PlMdbMonth[mid].readtime = ClockToReadTime(&PlcState[mid+PLC_BASEMETP].oktime, 1); break; //case 0x9012: case 0x9412: smallcpy(PlMdbMonth[mid].ene+8, buf, 4); FlagMonthSaved = 0; //PlMdbMonth[mid].readtime = ClockToReadTime(&PlcState[mid+PLC_BASEMETP].oktime, 1); break; //case 0x9013: case 0x9413: smallcpy(PlMdbMonth[mid].ene+12, buf, 4); FlagMonthSaved = 0; //PlMdbMonth[mid].readtime = ClockToReadTime(&PlcState[mid+PLC_BASEMETP].oktime, 1); break; //case 0x9014: case 0x9414: smallcpy(PlMdbMonth[mid].ene+16, buf, 4); FlagMonthSaved = 0; //PlMdbMonth[mid].readtime = ClockToReadTime(&PlcState[mid+PLC_BASEMETP].oktime, 1); break; case 0xC010: //状态 //PlMdbDay[mid].state[0] = buf[0]; //PlMdbDay[mid].state[1] = buf[1]; //FlagDaySaved = 0; //PlMdbMonth[mid].state[0] = buf[0]; //PlMdbMonth[mid].state[0] = buf[0]; break; case 0xF001: //重点用户电能量 { sysclock_t clock; unsigned int offset; //unsigned char kmid, impnum; //unsigned short metpid; /*metpid = mid + PLC_BASEMETP + 1; impnum = ParaMix.impuser.num; if(0 == impnum) break; else if(impnum > MAX_IMPORTANT_USER) impnum = MAX_IMPORTANT_USER; for(kmid=0; kmid<impnum; kmid++) { if(metpid == ParaMix.impuser.metid[kmid]) break; } if(kmid >= impnum) break;*/ if(mid >= MAX_IMPORTANT_USER) break; SysClockReadCurrent(&clock); offset = clock.hour; offset <<= 2; smallcpy(PlMdbImp[mid].ene+offset, buf, 4); FlagImpSaved = 0; } break; default: break; } }
static void PlRscStdForwardProc(struct amr_module_t *pmodule) { plc3762_pkt_t *pkt = (plc3762_pkt_t *)pmodule->link_send_buf; plc3762_pkt_t *prcv = (plc3762_pkt_t *)pmodule->link_recv_buf; plc_dest_t dest; #ifdef TEST_PLC int timeout = GetRskTimeout(); #else int timeout = PLRSC_READMET_TIMEOUT; #endif unsigned char *pdata; int i; pdata = pmodule->event_cmd_buf; memset((unsigned char*)&dest, 0, sizeof(plc_dest_t)); smallcpy(dest.dest, pmodule->MeterAddr, 6); dest.metid = 1; //没用 dest.proto = pmodule->app_proto;//透传DLMS:0,07:2 dest.portcfg = pmodule->port; dest.route.level = 0; dest.route.phase = 0; dest.src[0] = pmodule->module_id[0]; dest.src[1] = pmodule->module_id[1]; dest.src[2] = pmodule->module_id[2]; dest.src[3] = pmodule->module_id[3]; dest.src[4] = pmodule->module_id[4]; dest.src[5] = pmodule->module_id[5]; pkt->afn = PL3762_AFN_FORWARD; FN_DT(1, pkt->dt); pkt->data[0] = dest.proto; pkt->data[1] = (unsigned char)(pmodule->event_sendlen); memcpy(pkt->data+2, pdata, pmodule->event_sendlen); pkt->len = pmodule->event_sendlen + 2; pkt->ctrl = 0x41; if(Pl3762SendPkt(pmodule, &dest, 0)) goto mark_fail; //if(PlRsc3762RecvPktTimeout(pmodule, PL3762_AFN_FORWARD, 1, PLRSC_READMET_TIMEOUT)) goto mark_fail; if(PlRsc3762RecvPktTimeout(pmodule, PL3762_AFN_FORWARD, 1, timeout)) goto mark_fail; for(i=0; i<6; i++) { if(pmodule->link_recv_dest.src[i] != dest.dest[i]) goto mark_fail; } if(prcv->data[0] != dest.proto) goto mark_fail; if(prcv->len != (prcv->data[1]+2)) goto mark_fail; i = prcv->data[1] & 0xff; if(i <= 0) goto mark_fail; smallcpy(pmodule->event_echo_buf, prcv->data + 2, i); pmodule->event_echortn = i; pmodule->event_echoed = 1; return; mark_fail: pmodule->event_echortn = 0; pmodule->event_echoed = 1; return; }
//保存表库文件 // param table_name : 表名 // param qdata: 输出缓存区 // param qdatalen : 缓存区长度 int SaveToTable(char * table_name, unsigned char * qdata, unsigned int qdatalen) { #if 0 table_value = 0; sqlite3 * db = NULL; int result; char *errmsg = NULL; sqlite3_stmt *stat = NULL; char sql[128] = {0}; result = sqlite3_open(PARAM_DB, &db); if(result != SQLITE_OK){ PrintLog(0, "fail to open param.db!\n"); goto MARK_FAIL; } //const char * sql = "select count(*) as c from sqlite_master where type ='table' and name ='Unique_1'"; const char * s = "select * from sqlite_master"; strcpy(sql,s); result = sqlite3_exec(db, sql, table_callback, (void *)table_name, &errmsg); if(result != SQLITE_OK){ PrintLog(0, "查询表名称错误!错误码: %d, 错误原因: %s!\n", result, errmsg); //sqlite3_free(errmsg); goto MARK_FAIL; } /// #if 1 if(!table_value){ PrintLog(0, "表(%s)不存在,等待创建...\n", table_name); sprintf(sql, "create table %s(ID integer primary key,parauni blob)", table_name); result = sqlite3_exec(db, sql, NULL, NULL, &errmsg); if(result != SQLITE_OK){ PrintLog(0, "fail to create %s!错误码: %d, 错误原因: %s!\n", table_name, result, errmsg); goto MARK_FAIL; } sprintf(sql, "insert into %s(ID,parauni) values(0,?)", table_name); result = sqlite3_prepare(db, sql, -1, &stat, 0); if(result != SQLITE_OK || stat == NULL){ PrintLog(0, "fail to insert %s!\n", table_name); goto MARK_FAIL; } result = sqlite3_bind_blob(stat, 1, (const void *)qdata, (int)qdatalen, NULL); if(result != SQLITE_OK){ PrintLog(0, "fail to bind %s!\n", table_name); goto MARK_FAIL; } result = sqlite3_step(stat); if(result != SQLITE_DONE){ PrintLog(0, "fail to step insert!\n"); goto MARK_FAIL; } PrintLog(0, "success to insert data!\n"); sqlite3_finalize(stat); sqlite3_free(errmsg); sqlite3_close(db); return 0; } #endif sprintf(sql, "update %s set parauni = ? where ID = 0", table_name); result = sqlite3_prepare(db, sql, -1, &stat, 0); if(result != SQLITE_OK || stat == NULL){ PrintLog(0, "fail to update %s!\n", table_name); goto MARK_FAIL; } unsigned char arr[100*1024]; smallcpy(arr, qdata, qdatalen); result = sqlite3_bind_blob(stat, 1, (const void *)arr, qdatalen, 0); if(result != SQLITE_OK){ PrintLog(0, "fail to bind %s!\n", table_name); goto MARK_FAIL; } result = sqlite3_step(stat); if(result != SQLITE_DONE){ PrintLog(0, "fail to step update! result = %d\n", result); goto MARK_FAIL; } PrintLog(0, "success to update data!\n"); sqlite3_finalize(stat); sqlite3_free(errmsg); sqlite3_close(db); return 0; MARK_FAIL: sqlite3_finalize(stat); sqlite3_free(errmsg); sqlite3_close(db); #endif return -1; }
/** * @brief 读ESAM序列号 * @param revBuf 读到数据接口指针 * @return 0成功, 否则失败 */ int ReadESAMSerialNum(unsigned char *revBuf) { smallcpy(revBuf, SerialNum, 8); return 0; }
/** * @brief 接收数据帧 * @param dest 目的地址 * @param buf 接收缓存区指针 * @param len 接收缓存区长度 * @param timeout 超时时间(100ms) * @param 成功返回接收到的数据长度, 失败返回负数(参见错误码PLCERR_XXX) */ int Rs485BusRecvPkt(const plc_dest_t *dest, unsigned char *buf, int len, int timeout) { unsigned char state, recvlen, maxlen, cnt; unsigned char *pbuf = Rs485BusBuffer; unsigned char port; int times; AssertLog(len <= 0, "invalid len(%d)\n", len); state = 0; recvlen = 0; maxlen = 0; port = 1; cnt = 0; for(times=0; times<timeout; times++) { while(Rs485Recv(port, pbuf, 1) > 0) { PrintLog(LOGTYPE_DOWNLINK, "recv: %02X, %d\n", *pbuf, state); switch(state) { case 0: if(0x68 == *pbuf) { pbuf++; recvlen = 1; maxlen = 6; cnt = 0; state = 1; } break; case 1: pbuf++; recvlen++; cnt ++; if(cnt >= maxlen){ state = 2; } break; case 2: if(0x68 != *pbuf){ pbuf = Rs485BusBuffer; state = 0; break; } pbuf++; recvlen++; state = 3; break; case 3: pbuf++; recvlen++; state = 4; break; case 4: recvlen++; cnt = 0; maxlen = *pbuf; if(maxlen>128){ pbuf = Rs485BusBuffer; state = 0; break; } pbuf++; maxlen += 2; state = 5; break; case 5: recvlen++; cnt++; if(cnt >= maxlen) { if(0x16 == *pbuf){ goto mark_rcvend; } else{ pbuf = Rs485BusBuffer; state = 0; break; } } pbuf++; } } Sleep(10); } PrintLog(LOGTYPE_DOWNLINK, "Rs485 recv timeout(%d), time=%d00ms:\n", recvlen, times); if(recvlen) PrintHexLog(LOGTYPE_DOWNLINK, Rs485BusBuffer, recvlen); return PLCERR_TIMEOUT; mark_rcvend: PrintLog(LOGTYPE_DOWNLINK, "Rs485 recv(%d), time=%d00ms:\n", recvlen, times); PrintHexLog(LOGTYPE_DOWNLINK, Rs485BusBuffer, recvlen); smallcpy(buf, Rs485BusBuffer, recvlen); return recvlen; }