359@365

昨天打完羽毛球,今天早上发现起不来了, 359@365全身酸痛,蹲都蹲不下去,早上穿个鞋差点摔倒了,这种感觉真的挺爽的,因为好久没运动 这么一疼,感觉全身都放开了。
我来到公司,因为昨天是平安夜,今天就是外国人的圣诞节,虽然不是中国的指定节日,不过在中国已经很热门了,很多公司都会发些小礼物,像我们公司就发了,行政放着小歌曲,抬着一箱的礼物,我也不知道里面装着什么,非常激动,当派发到我的时候,我接下来盒子还蛮重的,我想应该是什么装饰品,结果打开是一个苹果?,感觉还不错,平安夜啊,当然需要象征节日的礼物了,因为我是12月份的,今天派发小礼物给我了,发了一个很厚实,很暖和的坐垫,还挺实在,因为现在是冬天了嘛。
最近吃那些上火食品太多,最近脸上长了好多红痘,加上冬季天气干燥,脸上也是,实在不舒服,看来要少吃上火的食品了,这广州吃东西也是比较火气,像我以前,在家根本不知道上火这个词汇的,来了广州才见识到上火是个什么样的状态,真的很难熬!那不能吃,那不能吃的,还好我不是个吃货,你说要是个吃货,得多痛苦那。
package android.telecom; 18 19 import android.annotation.Nullable; 20 import android.media.ToneGenerator; 21 import android.os.Parcel; 22 import android.os.Parcelable; 23 import android.telephony.Annotation; 24 import android.telephony.PreciseDisconnectCause; 25 import android.telephony.ims.ImsReasonInfo; 26 import android.text.TextUtils; 27 28 import java.util.Objects; 29 30 /** 31 * Describes the cause of a disconnected call. This always includes a code describing the generic 32 * cause of the disconnect. Optionally, it may include a label and/or description to display to the 33 * user. It is the responsibility of the {@link ConnectionService} to provide localized versions of 34 * the label and description. It also may contain a reason for the disconnect, which is intended for 35 * logging and not for display to the user. 36 */ 37 public final class DisconnectCause implements Parcelable { 38 39 /** Disconnected because of an unknown or unspecified reason. */ 40 public static final int UNKNOWN = TelecomProtoEnums.UNKNOWN; // = 0 41 /** Disconnected because there was an error, such as a problem with the network. */ 42 public static final int ERROR = TelecomProtoEnums.ERROR; // = 1 43 /** Disconnected because of a local user-initiated action, such as hanging up. */ 44 public static final int LOCAL = TelecomProtoEnums.LOCAL; // = 2 45 /** 46 * Disconnected because the remote party hung up an ongoing call, or because an outgoing call 47 * was not answered by the remote party. 48 */ 49 public static final int REMOTE = TelecomProtoEnums.REMOTE; // = 3 50 /** Disconnected because it has been canceled. */ 51 public static final int CANCELED = TelecomProtoEnums.CANCELED; // = 4 52 /** Disconnected because there was no response to an incoming call. */ 53 public static final int MISSED = TelecomProtoEnums.MISSED; // = 5 54 /** Disconnected because the user rejected an incoming call. */ 55 public static final int REJECTED = TelecomProtoEnums.REJECTED; // = 6 56 /** Disconnected because the other party was busy. */ 57 public static final int BUSY = TelecomProtoEnums.BUSY; // = 7 58 /** 59 * Disconnected because of a restriction on placing the call, such as dialing in airplane 60 * mode. 61 */ 62 public static final int RESTRICTED = TelecomProtoEnums.RESTRICTED; // = 8 63 /** Disconnected for reason not described by other disconnect codes. */ 64 public static final int OTHER = TelecomProtoEnums.OTHER; // = 9 65 /** 66 * Disconnected because the connection manager did not support the call. The call will be tried 67 * again without a connection manager. See {@link PhoneAccount#CAPABILITY_CONNECTION_MANAGER}. 68 */ 69 public static final int CONNECTION_MANAGER_NOT_SUPPORTED = 70 TelecomProtoEnums.CONNECTION_MANAGER_NOT_SUPPORTED; // = 10 71 72 /** 73 * Disconnected because the user did not locally answer the incoming call, but it was answered 74 * on another device where the call was ringing. 75 */ 76 public static final int ANSWERED_ELSEWHERE = TelecomProtoEnums.ANSWERED_ELSEWHERE; // = 11 77 78 /** 79 * Disconnected because the call was pulled from the current device to another device. 80 */ 81 public static final int CALL_PULLED = TelecomProtoEnums.CALL_PULLED; // = 12 82 83 /** 84 * Reason code (returned via {@link #getReason()}) which indicates that a call could not be 85 * completed because the cellular radio is off or out of service, the device is connected to 86 * a wifi network, but the user has not enabled wifi calling. 87 */ 88 public static final String REASON_WIFI_ON_BUT_WFC_OFF = "REASON_WIFI_ON_BUT_WFC_OFF"; 89 90 /** 91 * Reason code (returned via {@link #getReason()}), which indicates that the call was 92 * disconnected because IMS access is blocked. 93 */ 94 public static final String REASON_IMS_ACCESS_BLOCKED = "REASON_IMS_ACCESS_BLOCKED"; 95 96 /** 97 * Reason code (returned via {@link #getReason()}), which indicates that the connection service 98 * is setting the call's state to {@link Call#STATE_DISCONNECTED} because it is internally 99 * changing the representation of an IMS conference call to simulate a single-party call. 100 * 101 * This reason code is only used for communication between a {@link ConnectionService} and 102 * Telecom and should not be surfaced to the user. 103 */ 104 public static final String REASON_EMULATING_SINGLE_CALL = "EMULATING_SINGLE_CALL"; 105 106 /** 107 * This reason is set when a call is ended in order to place an emergency call when a 108 * {@link PhoneAccount} doesn't support holding an ongoing call to place an emergency call. This 109 * reason string should only be associated with the {@link #LOCAL} disconnect code returned from 110 * {@link #getCode()}. 111 */ 112 public static final String REASON_EMERGENCY_CALL_PLACED = "REASON_EMERGENCY_CALL_PLACED"; 113 114 private int mDisconnectCode; 115 private CharSequence mDisconnectLabel; 116 private CharSequence mDisconnectDescription; 117 private String mDisconnectReason; 118 private int mToneToPlay; 119 private int mTelephonyDisconnectCause; 120 private int mTelephonyPreciseDisconnectCause; 121 private ImsReasonInfo mImsReasonInfo; 122 123 /** 124 * Creates a new DisconnectCause. 125 * 126 * @param code The code for the disconnect cause. 127 */ 128 public DisconnectCause(int code) { 129 this(code, null, null, null, ToneGenerator.TONE_UNKNOWN); 130 } 131 132 /** 133 * Creates a new DisconnectCause. 134 * 135 * @param code The code for the disconnect cause. 136 * @param reason The reason for the disconnect. 137 */ 138 public DisconnectCause(int code, String reason) { 139 this(code, null, null, reason, ToneGenerator.TONE_UNKNOWN); 140 } 141 142 /** 143 * Creates a new DisconnectCause. 144 * 145 * @param code The code for the disconnect cause. 146 * @param label The localized label to show to the user to explain the disconnect. 147 * @param description The localized description to show to the user to explain the disconnect. 148 * @param reason The reason for the disconnect. 149 */ 150 public DisconnectCause(int code, CharSequence label, CharSequence description, String reason) { 151 this(code, label, description, reason, ToneGenerator.TONE_UNKNOWN); 152 } 153 154 /** 155 * Creates a new DisconnectCause. 156 * 157 * @param code The code for the disconnect cause. 158 * @param label The localized label to show to the user to explain the disconnect. 159 * @param description The localized description to show to the user to explain the disconnect. 160 * @param reason The reason for the disconnect. 161 * @param toneToPlay The tone to play on disconnect, as defined in {@link ToneGenerator}. 162 */ 163 public DisconnectCause(int code, CharSequence label, CharSequence description, String reason, 164 int toneToPlay) { 165 this(code, label, description, reason, toneToPlay, 166 android.telephony.DisconnectCause.ERROR_UNSPECIFIED, 167 PreciseDisconnectCause.ERROR_UNSPECIFIED, 168 null /* imsReasonInfo */); 169 } 170 171 /** 172 * Creates a new DisconnectCause instance. 173 * @param code The code for the disconnect cause. 174 * @param label The localized label to show to the user to explain the disconnect. 175 * @param description The localized description to show to the user to explain the disconnect. 176 * @param reason The reason for the disconnect. 177 * @param toneToPlay The tone to play on disconnect, as defined in {@link ToneGenerator}. 178 * @param telephonyDisconnectCause The Telephony disconnect cause. 179 * @param telephonyPreciseDisconnectCause The Telephony precise disconnect cause. 180 * @param imsReasonInfo The relevant {@link ImsReasonInfo}, or {@code null} if not available. 181 * @hide 182 */ 183 public DisconnectCause(int code, CharSequence label, CharSequence description, String reason, 184 int toneToPlay, @Annotation.DisconnectCauses int telephonyDisconnectCause, 185 @Annotation.PreciseDisconnectCauses int telephonyPreciseDisconnectCause, 186 @Nullable ImsReasonInfo imsReasonInfo) { 187 mDisconnectCode = code; 188 mDisconnectLabel = label; 189 mDisconnectDescription = description; 190 mDisconnectReason = reason; 191 mToneToPlay = toneToPlay; 192 mTelephonyDisconnectCause = telephonyDisconnectCause; 193 mTelephonyPreciseDisconnectCause = telephonyPreciseDisconnectCause; 194 mImsReasonInfo = imsReasonInfo; 195 } 196 197 /** 198 * Returns the code for the reason for this disconnect. 199 * 200 * @return The disconnect code. 201 */ 202 public int getCode() { 203 return mDisconnectCode; 204 } 205 206 /** 207 * Returns a short label which explains the reason for the disconnect cause and is for display 208 * in the user interface. If not null, it is expected that the In-Call UI should display this 209 * text where it would normally display the call state ("Dialing", "Disconnected") and is 210 * therefore expected to be relatively small. The {@link ConnectionService } is responsible for 211 * providing and localizing this label. If there is no string provided, returns null. 212 * 213 * @return The disconnect label. 214 */ 215 public CharSequence getLabel() { 216 return mDisconnectLabel; 217 } 218 219 /** 220 * Returns a description which explains the reason for the disconnect cause and is for display 221 * in the user interface. This optional text is generally a longer and more descriptive version 222 * of {@link #getLabel}, however it can exist even if {@link #getLabel} is empty. The In-Call UI 223 * should display this relatively prominently; the traditional implementation displays this as 224 * an alert dialog. The {@link ConnectionService} is responsible for providing and localizing 225 * this message. If there is no string provided, returns null. 226 * 227 * @return The disconnect description. 228 */ 229 public CharSequence getDescription() { 230 return mDisconnectDescription; 231 } 232 233 /** 234 * Returns an explanation of the reason for the disconnect. This is not intended for display to 235 * the user and is used mainly for logging. 236 * 237 * @return The disconnect reason. 238 */ 239 public String getReason() { 240 return mDisconnectReason; 241 } 242 243 /** 244 * Returns the telephony {@link android.telephony.DisconnectCause} for the call. 245 * @return The disconnect cause. 246 * @hide 247 */ 248 public @Annotation.DisconnectCauses int getTelephonyDisconnectCause() { 249 return mTelephonyDisconnectCause; 250 } 251 252 /** 253 * Returns the telephony {@link android.telephony.PreciseDisconnectCause} for the call. 254 * @return The precise disconnect cause. 255 * @hide 256 */ 257 public @Annotation.PreciseDisconnectCauses int getTelephonyPreciseDisconnectCause() { 258 return mTelephonyPreciseDisconnectCause; 259 } 260 261 /** 262 * Returns the telephony {@link ImsReasonInfo} associated with the call disconnection. 263 * @return The {@link ImsReasonInfo} or {@code null} if not known. 264 * @hide 265 */ 266 public @Nullable ImsReasonInfo getImsReasonInfo() { 267 return mImsReasonInfo; 268 } 269 270 /** 271 * Returns the tone to play when disconnected. 272 * 273 * @return the tone as defined in {@link ToneGenerator} to play when disconnected. 274 */ 275 public int getTone() { 276 return mToneToPlay; 277 } 278 279 public static final @android.annotation.NonNull Creator<DisconnectCause> CREATOR 280 = new Creator<DisconnectCause>() { 281 @Override 282 public DisconnectCause createFromParcel(Parcel source) { 283 int code = source.readInt(); 284 CharSequence label = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 285 CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source); 286 String reason = source.readString(); 287 int tone = source.readInt(); 288 int telephonyDisconnectCause = source.readInt(); 289 int telephonyPreciseDisconnectCause = source.readInt(); 290 ImsReasonInfo imsReasonInfo = source.readParcelable(null, android.telephony.ims.ImsReasonInfo.class); 291 return new DisconnectCause(code, label, description, reason, tone, 292 telephonyDisconnectCause, telephonyPreciseDisconnectCause, imsReasonInfo); 293 } 294 295 @Override 296 public DisconnectCause[] newArray(int size) { 297 return new DisconnectCause[size]; 298 } 299 }; 300 301 @Override 302 public void writeToParcel(Parcel destination, int flags) { 303 destination.writeInt(mDisconnectCode); 304 TextUtils.writeToParcel(mDisconnectLabel, destination, flags); 305 TextUtils.writeToParcel(mDisconnectDescription, destination, flags); 306 destination.writeString(mDisconnectReason); 307 destination.writeInt(mToneToPlay); 308 destination.writeInt(mTelephonyDisconnectCause); 309 destination.writeInt(mTelephonyPreciseDisconnectCause); 310 destination.writeParcelable(mImsReasonInfo, 0); 311 } 312 313 @Override 314 public int describeContents() { 315 return 0; 316 } 317 318 @Override 319 public int hashCode() { 320 return Objects.hashCode(mDisconnectCode) 321 + Objects.hashCode(mDisconnectLabel) 322 + Objects.hashCode(mDisconnectDescription) 323 + Objects.hashCode(mDisconnectReason) 324 + Objects.hashCode(mToneToPlay) 325 + Objects.hashCode(mTelephonyDisconnectCause) 326 + Objects.hashCode(mTelephonyPreciseDisconnectCause) 327 + Objects.hashCode(mImsReasonInfo); 328 } 329 330 @Override 331 public boolean equals(Object o) { 332 if (o instanceof DisconnectCause) { 333 DisconnectCause d = (DisconnectCause) o; 334 return Objects.equals(mDisconnectCode, d.getCode()) 335 && Objects.equals(mDisconnectLabel, d.getLabel()) 336 && Objects.equals(mDisconnectDescription, d.getDescription()) 337 && Objects.equals(mDisconnectReason, d.getReason()) 338 && Objects.equals(mToneToPlay, d.getTone()) 339 && Objects.equals(mTelephonyDisconnectCause, d.getTelephonyDisconnectCause()) 340 && Objects.equals(mTelephonyPreciseDisconnectCause, 341 d.getTelephonyPreciseDisconnectCause()) 342 && Objects.equals(mImsReasonInfo, d.getImsReasonInfo()); 343 } 344 return false; 345 } 346 347 @Override 348 public String toString() { 349 String code = ""; 350 switch (mDisconnectCode) { 351 case UNKNOWN: 352 code = "UNKNOWN"; 353 break; 354 case ERROR: 355 code = "ERROR"; 356 break; 357 case LOCAL: 358 code = "LOCAL"; 359 break; 360 case REMOTE: 361 code = "REMOTE"; 362 break; 363 case CANCELED: 364 code = "CANCELED"; 365 break; 366 case MISSED: 367 code = "MISSED"; 368 break; 369 case REJECTED: 370 code = "REJECTED"; 371 break; 372 case BUSY: 373 code = "BUSY"; 374 break; 375 case RESTRICTED: 376 code = "RESTRICTED"; 377 break; 378 case OTHER: 379 code = "OTHER"; 380 break; 381 case CONNECTION_MANAGER_NOT_SUPPORTED: 382 code = "CONNECTION_MANAGER_NOT_SUPPORTED"; 383 break; 384 case CALL_PULLED: 385 code = "CALL_PULLED"; 386 break; 387 case ANSWERED_ELSEWHERE: 388 code = "ANSWERED_ELSEWHERE"; 389 break; 390 default: 391 code = "invalid code: " + mDisconnectCode; 392 break; 393 } 394 String label = mDisconnectLabel == null ? "" : mDisconnectLabel.toString(); 395 String description = mDisconnectDescription == null 396 ? "" : mDisconnectDescription.toString(); 397 String reason = mDisconnectReason == null ? "" : mDisconnectReason; 398 return "DisconnectCause [ Code: (" + code + ")" 399 + " Label: (" + label + ")" 400 + " Description: (" + description + ")" 401 + " Reason: (" + reason + ")" 402 + " Tone: (" + mToneToPlay + ") " 403 + " TelephonyCause: " + mTelephonyDisconnectCause + "/" 404 + mTelephonyPreciseDisconnectCause 405 + " ImsReasonInfo: " 406 + mImsReasonInfo 407 + "]"; 408 } 409 } telephonycause的值是怎么来的
08-24
#ifndef __INCLUDE_COMTRADE_FORMAT_H 118: #define __INCLUDE_COMTRADE_FORMAT_H 119: 120: 121: 122: /* 123: * 头文件 124: */ 125: #include "base_type.h" 126: 127: 128: #if defined (__cplusplus) 129: extern "C" { 130: #endif /* defined (__cplusplus) */ 131: 132: 133: /* 134: * 宏开关 定义为文件读写 135: */ 136: #define CMTR_IOFILE 137: 138: 139: 140: /* 141: * 宏定义文件的读写操作,可以根据需要改写该接口,如重定义 142: * 为网口的recv\send、串口r\w等。 143: * 144: * _my_read_cmtr_bufn/_my_read_cmtr_bufn - cmtr的读写操作 145: * @pfd: 读写地址,可以为文件的fd、或者buffer地址等 146: * @buf: 缓冲区地址 147: * @count: 需要读写的字节数 148: * 149: */ 150: #if defined(CMTR_IOFILE) 151: typedef int _my_cmtr_ioptr; 152: #define _my_read_cmtr_bufn(pfd, buf, count) \ 153: do { \ 154: if (read((pfd), (buf), (count)) <= 0) { \ 155: (pfd) = -1; \ 156: } \ 157: } while(0); 158: #define _my_write_cmtr_bufn(pfd, buf, count) \ 159: do { \ 160: if (write((pfd), (buf), (count)) <= 0) {\ 161: (pfd) = -1; \ 162: } \ 163: } while(0); 164: #define _my_check_cmtr_ptr(pfd) \ 165: (((pfd) != -1) && ((pfd) != 0)) 166: #elif defined(CMTR_IOBUFFER) 167: typedef u8* _my_cmtr_ioptr; 168: #define _my_read_cmtr_bufn(pfd, buf, count) \ 169: do { \ 170: memcpy((buf), (pfd), (count)); \ 171: (pfd) += (count); \ 172: } while(0); 173: #define _my_write_cmtr_bufn(pfd, buf, count) \ 174: do { \ 175: memcpy((pfd), (buf), (count)); \ 176: (pfd) += (count); \ 177: } while(0); 178: #define _my_check_cmtr_ptr(pfd) \ 179: (((pfd) != -1) && ((pfd) != 0)) 180: #endif 181: 182: 183: 184: /* 185: * 关于comtrade文件配置文件的宏定义。 186: * 在此采用预定义最大个数方法,避免动态内存管理的问题。 187: * 188: * 相关字符串最大字符个数,一般不会超过16个; 189: * 模拟量端口最大个数,一般不会超过64个; 190: * 数字量量端口最大个数,一般不会超过64个; 191: * 采样率最大个数,一般不会超过8个; 192: * 193: */ 194: #define CMTR_STRING_MAX_LENGTH 64 195: #define CMTR_ANALOG_MAX_COUNT 255 196: #define CMTR_DIGIT_MAX_COUNT 255 197: #define CMTR_SMPRATE_MAX_COUNT 255 198: 199: 200: 201: /* 202: * cmtr_cfg_analog - 配置文件模拟量信息 203: * @index: 模拟量端口序号(只是编号,解析时不做序号用); 204: * @name: 模拟量端口名称; 205: * @phase: 模拟量端口相标识,值如(A、B、C、N等); 206: * @element:标识(还未知,待补充),一般为空; 207: * @unit: 模拟量端口数值的单位,该单位常用来区分该端口是电流还是电流,值如:kV、V、A、mA等; 208: * @factor_a: 系数a,一般为整数,可以是浮点数; 209: * @factor_b: 系数b,一般为整数,可以是浮点数; 210: * @offset_time: 时间偏移,指第一个点的时间偏移量,一般为0; 211: * @smp_min: 通道的最小采用值,一般为整数,国内有些变态的仪器会生成浮点数(在次不支持); 212: * @smp_max: 通道的最大采用值,一般为整数,国内有些变态的仪器会生成浮点数(在次不支持); 213: * 214: * 通道采样的实际值计算方法:实际值 = factor_a * smp_value + factor_b;所以根据该公式,可以计算 215: * 通道的最小值为:factor_a * smp_min + factor_b,最大值为:factor_a * smp_max + factor_b。 216: * 217: * 注:本来smp_min、smp_max为两个字节的一个数据(即最大为65535),但不同厂家会生成很大的四字节数据, 218: * 所以采用s32类型;factor_a、factor_b用double类型,用float可能会丢精度;为了提供解析程序的适 219: * 应性,以适应国内各种变态的有标准不遵循的厂家的仪器生成的cmtr文件。 220: * 221: */ 222: struct cmtr_cfg_analog { 223: s32 index; 224: u8 name[CMTR_STRING_MAX_LENGTH]; 225: u8 phase[CMTR_STRING_MAX_LENGTH]; 226: u8 element[CMTR_STRING_MAX_LENGTH]; 227: u8 unit[CMTR_STRING_MAX_LENGTH]; 228: f64 factor_a; 229: f64 factor_b; 230: s32 offset_time; 231: s32 smp_min; 232: s32 smp_max; 233: }; 234: 235: 236: /* 237: * cmtr_cfg_digit - 配置文件数字量信息 238: * @index: 数字量端口序号(只是编号,解析时不做序号用); 239: * @name: 数字量端口名称; 240: * @state: 数字量起始状态值,一般为1或者0,很少情况下会为2; 241: * 242: */ 243: struct cmtr_cfg_digit { 244: s32 index; 245: u8 name[CMTR_STRING_MAX_LENGTH]; 246: s8 state; 247: }; 248: 249: /* 250: * cmtr_cfg_smprate_info - 配置文件采样点信息 251: * @rate: 采样率,一般为整数,也有小数表示的; 252: * @point: 该采样率下采样的点数,为整数; 253: * 254: */ 255: struct cmtr_cfg_smprate { 256: f32 rate; 257: s32 point; 258: }; 259: 260: /* 261: * cmtr_cfg_info - 配置文件信息。 262: * @station_name: 厂站名称; 263: * @kymograph_id: 录波器编号; 264: * @analog_count: 模拟量个数; 265: * @digit_count: 数字量个数; 266: * @analogs: 模拟量信息; 267: * @digits: 数字量信息; 268: * @frequency: 基本频率,一般为额定频率,指的是电网频率; 269: * @smprate_count: 采样率个数; 270: * @smprates: 采样率信息; 271: * @begin_time: 录波开始时间; 272: * @end_time: 录波结束时间; 273: * @file_type: 数据文件类型,可以“ASCII”和“Binary”,ASCII类型为dat文件可以用记事本打开看详 274: * 细的采样信息;binary格式的只能用特殊的工具查看,为二进制数据文件; 275: * 276: */ 277: typedef struct cmtr_cfg_info { 278: u8 station_name[CMTR_STRING_MAX_LENGTH]; 279: u8 kymograph_id[CMTR_STRING_MAX_LENGTH]; 280: s32 analog_count; 281: s32 digit_count; 282: struct cmtr_cfg_analog analogs[CMTR_ANALOG_MAX_COUNT]; 283: struct cmtr_cfg_digit digits[CMTR_DIGIT_MAX_COUNT]; 284: f32 frequency; 285: s32 smprate_count; 286: struct cmtr_cfg_smprate smprates[CMTR_SMPRATE_MAX_COUNT]; 287: u8 begin_time[CMTR_STRING_MAX_LENGTH]; 288: u8 end_time[CMTR_STRING_MAX_LENGTH]; 289: u8 file_type[CMTR_STRING_MAX_LENGTH]; 290: }; 291: 292: 293: 294: /* 295: * cmtr_dat_smpdot - 数据文件中的采样点数据信息. 296: * @index: 端口序号(只是编号,解析时不做序号用); 297: * @time: 采样点采样时间偏移量,单位微妙; 298: * @analogs: 模拟量信息,一般为有符号整数,国内有些变态的仪器会生成浮点数(在此不支持); 299: * @digits: 数字量信息,为有符号整数; 300: * 301: */ 302: struct cmtr_dat_smpdot{ 303: s32 index; 304: s32 time; 305: s32 analogs[CMTR_ANALOG_MAX_COUNT]; 306: s8 digits[CMTR_DIGIT_MAX_COUNT]; 307: }; 308: 309: 310: 311: 312: 313: /* 314: * write_cmtr_cfg_info - 写cmtr配置文件. 315: * @pfd: 输入输出参数,地址 316: * @cfg:输入参数,cmtr(cfg文件)结构体 317: * @counter: 输出参数,写入的字节计数器; 318: * 319: * 返回当前pfd指针,写失败返回NULL 320: * 321: */ 322: _my_cmtr_ioptr write_cmtr_cfg_info(_my_cmtr_ioptr pfd, 323: struct cmtr_cfg_info *cfg, 324: int *counter); 325: 326: 327: /* 328: * write_cmtr_dat_smpdot_ascii - 写cmtr采样点数据信息(ascii格式). 329: * @pfd: 输入输出参数,地址 330: * @analog_count: 输入参数,模拟量个数; 331: * @digit_count: 输入参数,数字量个数; 332: * @dot: 输入参数,采样点信息; 333: * @counter: 输出参数,写入的字节计数器; 334: * 335: * 返回当前pfd指针,写失败返回NULL 336: * 337: */ 338: _my_cmtr_ioptr write_cmtr_dat_smpdot_ascii(_my_cmtr_ioptr pfd, 339: int analog_count, int digit_count, 340: struct cmtr_dat_smpdot *dot, 341: int* counter); 342: 343: /* 344: * write_cmtr_dat_smpdot_binary - 写cmtr采样点数据信息(binary格式). 345: * @pfd: 输入输出参数,地址 346: * @big_endian_tag: 输入参数,标识文件中数据的字节顺序,为FALSE按照小端写(默认值),True按照大端写; 347: * @analog_count: 输入参数,模拟量个数; 348: * @digit_count: 输入参数,数字量个数; 349: * @dot: 输入参数,采样点信息; 350: * @counter: 输出参数,写入的字节计数器; 351: * 352: * 返回当前pfd指针,写失败返回NULL 353: * 354: */ 355: _my_cmtr_ioptr write_cmtr_dat_smpdot_binary(_my_cmtr_ioptr pfd, 356: u8 big_endian_tag, 357: int analog_count, int digit_count, 358: struct cmtr_dat_smpdot *dot, 359: int* counter); 360: 361: 362: /* 363: * read_cmtr_cfg_info - 读cmtr配置文件. 364: * @pfd: 输入输出参数,地址 365: * @cfg:输出参数,cmtr(cfg文件)结构体 366: * @counter: 输出参数,读取的字节计数器; 367: * 368: * 返回当前pfd指针,读失败返回NULL 369: * 370: */ 371: _my_cmtr_ioptr read_cmtr_cfg_info(_my_cmtr_ioptr pfd, 372: struct cmtr_cfg_info *cfg, 373: int* counter); 374: 375: 376: /* 377: * read_cmtr_dat_smpdot_ascii - 读ascii格式cmtr采样点数据信息. 378: * @pfd: 输入输出参数,地址 379: * @read_buf: 输入参数,读缓冲,在外部申请内存,避免在内部频繁申请、释放内存; 380: * @buf_size: 输入参数,读缓冲区的大小; 381: * @analog_count: 输入参数,模拟量个数; 382: * @digit_count: 输入参数,数字量个数; 383: * @dot: 输出参数,采样点信息; 384: * @the_smp_mins: 输出参数,统计最小值,为数组,个数至少为analog_count个,值为NULL时忽略统计; 385: * @the_smp_maxs: 输出参数,统计最大值,为数组,个数至少为analog_count个,值为NULL时忽略统计; 386: * @counter: 输出参数,读取的字节计数器; 387: * 388: * 返回当前pfd指针,读失败返回NULL 389: * 390: */ 391: _my_cmtr_ioptr read_cmtr_dat_smpdot_ascii(_my_cmtr_ioptr pfd, 392: u8 *read_buf, int buf_size, 393: int analog_count, int digit_count, 394: struct cmtr_dat_smpdot *dot, 395: u16* the_smp_mins, u16* the_smp_maxs, 396: int* counter); 397: 398: /* 399: * read_cmtr_dat_smpdot_binary - 读bin格式cmtr采样点数据信息. 400: * @pfd: 输入输出参数,地址 401: * @big_endian_tag: 输入参数,标识文件中数据的字节顺序,为FALSE按照小端读(默认值),True按照大端读; 402: * @analog_count: 输入参数,模拟量个数; 403: * @digit_count: 输入参数,数字量个数; 404: * @dot: 输出参数,采样点信息; 405: * @the_smp_mins: 输出参数,统计最小值,为数组,个数至少为analog_count个,值为NULL时忽略统计; 406: * @the_smp_maxs: 输出参数,统计最大值,为数组,个数至少为analog_count个,值为NULL时忽略统计; 407: * @counter: 输出参数,读取的字节计数器; 408: * 409: * 返回当前pfd指针,读失败返回NULL 410: * 411: */ 412: _my_cmtr_ioptr read_cmtr_dat_smpdot_binary(_my_cmtr_ioptr pfd, u8 big_endian_tag, 413: int analog_count, int digit_count, 414: struct cmtr_dat_smpdot *dot, 415: u32* the_smp_mins, u32* the_smp_maxs, 416: int* counter); 417: 418: /* 419: * print_cmtr_cfg_info - 打印cmtr文件配置数. 420: * @cfg: 输入参数,cmtr文件配置数据; 421: * 422: */ 423: void print_cmtr_cfg_info(struct cmtr_cfg_info *cfg); 424: 425: /* 426: * print_cmtr_dat_smpdot - 打印cmtr数据文件采样点. 427: * @cfg: 输入参数,cmtr文件配置数据; 428: * @analog_count: 输入参数,模拟量个数; 429: * @digit_count: 输入参数,数字量个数; 430: * @dot: 输入参数,采样点信息; 431: * 432: */ 433: void print_cmtr_dat_smpdot(int analog_count, int digit_count, 434: struct cmtr_dat_smpdot *dot); 435: 436: 437: 438: #if defined (__cplusplus) 439: } 440: #endif /* defined (__cplusplus) */ 441: 442: 443: #endif /* __INCLUDE_COMTRADE_FORMAT_H */ comtrade_format.c 1: /* 2: * 分析解析COMTRADE(IEEE标准电力系统暂态数据交换通用格式)文件格式。 3: * 4: * 5: * 本代码支持win32平台和linux平台。 6: * 7: * Copyright,lizhi<ibox> 8: * 9: * 2012-10-10 V1.0 lizhi<QQ:252240557,msn:ddgooo@hotmail.com> created 10: * 11: */ 12: 13: /* 14: * 头文件 15: */ 16: #include "base_type.h" 17: #include "base_include.h" 18: #include "base_debug.h" 19: #include "base_endian.h" 20: #include "base_function.h" 21: #include "comtrade_format.h" 22: 23: 24: /* 25: * 测试宏开关 26: */ 27: ///* 28: #define CMTR_CONSOLE_DEMO 29: //*/ 30: 31: 32: /* 33: * _my_read_cmtr_data/_my_write_cmtr_data - 读取/写入并且转换cmtr数据。 34: * @src: 读写地址,为buffer地址; 35: * @data: 读取/写入的数据; 36: * @count: 需要读取/写入的字节个数; 37: * @counter: 读取/写入的字节计数器; 38: * 39: */ 40: #define _my_read_cmtr_data(src, data, count, counter) \ 41: do { \ 42: if (_my_check_cmtr_ptr(src)) { \ 43: _my_read_cmtr_bufn((src), (data), (count)); \ 44: (counter) += (count); \ 45: } \ 46: } while(0); 47: #define _my_write_cmtr_data(src, data, count, counter) \ 48: do { \ 49: if (_my_check_cmtr_ptr(src)) { \ 50: _my_write_cmtr_bufn((src), (data), (count)); \ 51: (counter) +=(count); \ 52: } \ 53: } while(0); 54: 55: /* 56: * write_cmtr_cfg_info - 写cmtr配置文件. 57: * @pfd: 输入输出参数,地址 58: * @cfg:输入参数,cmtr(cfg文件)结构体 59: * @counter: 输出参数,写入的字节计数器; 60: * 61: * 返回当前pfd指针,写失败返回NULL 62: * 63: */ 64: _my_cmtr_ioptr write_cmtr_cfg_info(_my_cmtr_ioptr pfd, struct cmtr_cfg_info *cfg, int *counter) 65: { 66: u32 strlenr = 0; 67: u32 strmaxl = CMTR_STRING_MAX_LENGTH * 10; 68: u8* strline = (u8 *)_my_buf_malloc((size_t)(strmaxl)); 69: u32 index = 0; 70: 71: _my_cmtr_ioptr curr_pfd = pfd; 72: 73: memset(strline, '\0', strmaxl); 74: strlenr = sprintf(strline, "%s,%s\n", cfg->station_name, cfg->kymograph_id); 75: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 76: 77: memset(strline, '\0', strmaxl); 78: strlenr = sprintf(strline, "%d,%dA,%dD\n", cfg->analog_count + cfg->digit_count, cfg->analog_count, cfg->digit_count); 79: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 80: 81: for (index = 0; index < cfg->analog_count; index++) { 82: memset(strline, '\0', strmaxl); 83: strlenr = sprintf(strline, "%d,%s,%s,%s,%s,%lf,%lf,%d,%d,%d\n", 84: cfg->analogs[index].index, 85: cfg->analogs[index].name, 86: cfg->analogs[index].phase, 87: cfg->analogs[index].element, 88: cfg->analogs[index].unit, 89: cfg->analogs[index].factor_a, 90: cfg->analogs[index].factor_b, 91: cfg->analogs[index].offset_time, 92: cfg->analogs[index].smp_min, 93: cfg->analogs[index].smp_max); 94: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 95: } 96: 97: for (index = 0; index < cfg->digit_count; index++) { 98: memset(strline, '\0', strmaxl); 99: strlenr = sprintf(strline, "%d,%s,%d\n", 100: cfg->digits[index].index, 101: cfg->digits[index].name, 102: cfg->digits[index].state); 103: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 104: } 105: 106: memset(strline, '\0', strmaxl); 107: strlenr = sprintf(strline, "%f\n", cfg->frequency); 108: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 109: 110: memset(strline, '\0', strmaxl); 111: strlenr = sprintf(strline, "%d\n", cfg->smprate_count); 112: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 113: for (index = 0; index < cfg->smprate_count; index++) { 114: memset(strline, '\0', strmaxl); 115: strlenr = sprintf(strline, "%f,%d\n", cfg->smprates[index].rate, cfg->smprates[index].point); 116: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 117: } 118: 119: memset(strline, '\0', strmaxl); 120: strlenr = sprintf(strline, "%s\n", cfg->begin_time); 121: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 122: memset(strline, '\0', strmaxl); 123: strlenr = sprintf(strline, "%s\n", cfg->end_time); 124: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 125: strlenr = sprintf(strline, "%s\n", cfg->file_type); 126: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 127: 128: _my_buf_free(strline); 129: 130: return curr_pfd; 131: } 132: 133: 134: /* 135: * write_cmtr_dat_smpdot_ascii - 写cmtr采样点数据信息(ascii格式). 136: * @pfd: 输入输出参数,地址 137: * @analog_count: 输入参数,模拟量个数; 138: * @digit_count: 输入参数,数字量个数; 139: * @dot: 输入参数,采样点信息; 140: * @counter: 输出参数,写入的字节计数器; 141: * 142: * 返回当前pfd指针,写失败返回NULL 143: * 144: */ 145: _my_cmtr_ioptr write_cmtr_dat_smpdot_ascii(_my_cmtr_ioptr pfd, int analog_count, int digit_count, struct cmtr_dat_smpdot *dot, int* counter) 146: { 147: u32 strlenr = 0; 148: u32 strmaxl = CMTR_STRING_MAX_LENGTH; 149: u8* strline = (u8 *)_my_buf_malloc((size_t)(strmaxl)); 150: int index = 0; 151: 152: _my_cmtr_ioptr curr_pfd = pfd; 153: 154: _my_assert(pfd && dot); 155: 156: memset(strline, '\0', strmaxl); 157: strlenr = sprintf(strline, "%d,%d", dot->index, dot->time); 158: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 159: for (index = 0; index < analog_count; index++) { 160: memset(strline, '\0', strmaxl); 161: strlenr = sprintf(strline, ",%d", dot->analogs[index]); 162: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 163: } 164: for (index = 0; index < digit_count; index++) { 165: memset(strline, '\0', strmaxl); 166: strlenr = sprintf(strline, ",%d", dot->digits[index]); 167: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 168: } 169: memset(strline, '\0', strmaxl); 170: strlenr = sprintf(strline, "\n"); 171: _my_write_cmtr_data(curr_pfd, strline, strlenr, *counter); 172: 173: _my_buf_free(strline); 174: 175: return curr_pfd; 176: } 177: 178: 179: /* 180: * write_cmtr_dat_smpdot_binary - 写cmtr采样点数据信息(binary格式). 181: * @pfd: 输入输出参数,地址 182: * @big_endian_tag: 输入参数,标识文件中数据的字节顺序,为FALSE按照小端写(默认值),True按照大端写; 183: * @analog_count: 输入参数,模拟量个数; 184: * @digit_count: 输入参数,数字量个数; 185: * @dot: 输入参数,采样点信息; 186: * @counter: 输出参数,写入的字节计数器; 187: * 188: * 返回当前pfd指针,写失败返回NULL 189: * 190: */ 191: _my_cmtr_ioptr write_cmtr_dat_smpdot_binary(_my_cmtr_ioptr pfd, u8 big_endian_tag, int analog_count, int digit_count, struct cmtr_dat_smpdot *dot, int* counter) 192: { 193: s16 data16 = 0x00; 194: s32 data32 = 0x00; 195: int oldnum = 0; 196: 197: s16 datatp = 0x00; 198: 199: int index = 0; 200: 201: _my_cmtr_ioptr curr_pfd = pfd; 202: 203: oldnum = (*counter); 204: data32 = big_endian_tag ? _my_htob32(dot->index) : _my_htol32(dot->index); 205: _my_write_cmtr_data(curr_pfd, &data32, 4, *counter); 206: if ((*counter) <= oldnum) { 207: return NULL; 208: } 209: oldnum = (*counter); 210: data32 = big_endian_tag ? _my_htob32(dot->time) : _my_htol32(dot->time); 211: _my_write_cmtr_data(curr_pfd, &data32, 4, *counter); 212: if ((*counter) <= oldnum) { 213: return NULL; 214: } 215: for (index = 0; index < analog_count; index++) { 216: oldnum = (*counter); 217: datatp = (s16)(dot->analogs[index]); 218: data16 = big_endian_tag ? _my_htob16(datatp) : _my_htol16(datatp); 219: _my_write_cmtr_data(curr_pfd, &data16, 2, *counter); 220: if ((*counter) <= oldnum) { 221: return NULL; 222: } 223: } 224: 225: data16 = 0x0000; 226: for (index = 0; index < digit_count; index++) { 227: if (dot->digits[index]) { 228: data16 |= (0x0001 << (index % 16)); 229: } 230: if (((index % 16) == 0) && (index != 0)) { 231: oldnum = (*counter); 232: data16 = big_endian_tag ? _my_htob16(data16) : _my_htol16(data16); 233: _my_write_cmtr_data(curr_pfd, &data16, 2, *counter); 234: if ((*counter) <= oldnum) { 235: return NULL; 236: } 237: } 238: } 239: if (((index % 16) != 1) && (index != 0)) { 240: oldnum = (*counter); 241: data16 = big_endian_tag ? _my_htob16(data16) : _my_htol16(data16); 242: _my_write_cmtr_data(curr_pfd, &data16, 2, *counter); 243: if ((*counter) <= oldnum) { 244: return NULL; 245: } 246: } 247: 248: return curr_pfd; 249: } 250: 251: 252: /* 253: * read_cmtr_cfg_line - 读cmtr配置文件一行,跳过空行. 254: * @pfd: 输入输出参数,地址; 255: * @strline:输出参数,内容缓冲区; 256: * @size:输入参数,缓冲区大小; 257: * @strlend: 输出参数,读取的line的结束字符指针; 258: * @counter: 输出参数,读取的字节计数器; 259: * 260: * 返回当前pfd指针,读失败返回NULL。 261: * 262: */ 263: static _my_cmtr_ioptr read_cmtr_cfg_line(_my_cmtr_ioptr pfd, char *strline, int size, char **strlend,int *counter) 264: { 265: int pos = 0; 266: int oldnum = 0; 267: u8 datard = 0; 268: _my_cmtr_ioptr curr_pfd = pfd; 269: (*strlend) = NULL; 270: if (size <= 0) { 271: return NULL; 272: } 273: if ((!strline) || (!counter)) { 274: return NULL; 275: } 276: 277: memset(strline, '\0', size); 278: while (_my_check_cmtr_ptr(curr_pfd)) { 279: oldnum = (*counter); 280: datard = '\0'; 281: _my_read_cmtr_data(curr_pfd, &datard, 1, *counter); 282: if ((*counter) > oldnum) { 283: if (( datard != '\0') && ( datard != '\r') && ( datard != '\n')) { 284: if ((*strlend) < (strline + size)) { 285: (*(strline + pos)) = datard; 286: (*strlend) = strline + pos; 287: } 288: pos += 1; 289: continue; 290: } else { 291: break; 292: } 293: } 294: } 295: if (pos == 0) { 296: if (_my_check_cmtr_ptr(curr_pfd)) { 297: return read_cmtr_cfg_line(curr_pfd, strline, size, strlend, counter); 298: } else { 299: return NULL; 300: } 301: } 302: 303: return curr_pfd; 304: } 305: 306: /* 307: * read_cmtr_cfg_one_analog - 分析一行模拟量信息. 308: * @analog: 输出参数,模拟量信息; 309: * @strline:输入参数,内容缓冲区; 310: * @size:输入参数,缓冲区大小; 311: * @strlend: 输入参数,读取的line结束指针; 312: * 313: * 返回TRUE成功,失败返回FALSE。 314: * 315: */ 316: static u8 read_cmtr_cfg_one_analog(struct cmtr_cfg_analog *analog, char *strline, int size, char *strlend) 317: { 318: int dataint = 0; 319: f64 dataflt = 0; 320: char* ptrpos = 0; 321: char* strlcur = strline; 322: 323: ptrpos = strchr(strlcur, ','); 324: if ((!ptrpos) || (ptrpos >= strlend)) { 325: return FALSE; 326: } 327: if (sscanf(strlcur, "%d%*s", &dataint) <= 0) { 328: return FALSE; 329: } 330: analog->index = dataint; 331: 332: strlcur = ptrpos += 1; 333: ptrpos = strchr(strlcur, ','); 334: if ((!ptrpos) || (ptrpos >= strlend)) { 335: return FALSE; 336: } 337: memset(analog->name, '\0', CMTR_STRING_MAX_LENGTH); 338: memcpy(analog->name, strlcur, ptrpos-strlcur); 339: 340: strlcur = ptrpos += 1; 341: ptrpos = strchr(strlcur, ','); 342: if ((!ptrpos) || (ptrpos >= strlend)) { 343: return FALSE; 344: } 345: memset(analog->phase, '\0', CMTR_STRING_MAX_LENGTH); 346: memcpy(analog->phase, strlcur, ptrpos-strlcur); 347: 348: strlcur = ptrpos += 1; 349: ptrpos = strchr(strlcur, ','); 350: if ((!ptrpos) || (ptrpos >= strlend)) { 351: return FALSE; 352: } 353: memset(analog->element, '\0', CMTR_STRING_MAX_LENGTH); 354: memcpy(analog->element, strlcur, ptrpos-strlcur); 355: 356: strlcur = ptrpos += 1; 357: ptrpos = strchr(strlcur, ','); 358: if ((!ptrpos) || (ptrpos >= strlend)) { 359: return FALSE; 360: } 361: memset(analog->unit, '\0', CMTR_STRING_MAX_LENGTH); 362: memcpy(analog->unit, strlcur, ptrpos-strlcur); 363: 364: strlcur = ptrpos += 1; 365: ptrpos = strchr(strlcur, ','); 366: if ((!ptrpos) || (ptrpos >= strlend)) { 367: return FALSE; 368: } 369: if (sscanf(strlcur, "%lf%*s", &dataflt) <= 0) { 370: return FALSE; 371: } 372: analog->factor_a = dataflt; 373: 374: strlcur = ptrpos += 1; 375: ptrpos = strchr(strlcur, ','); 376: if ((!ptrpos) || (ptrpos >= strlend)) { 377: return FALSE; 378: } 379: if (sscanf(strlcur, "%lf%*s", &dataflt) <= 0) { 380: return FALSE; 381: } 382: analog->factor_b = dataflt; 383: 384: strlcur = ptrpos += 1; 385: ptrpos = strchr(strlcur, ','); 386: if ((!ptrpos) || (ptrpos >= strlend)) { 387: return FALSE; 388: } 389: if (sscanf(strlcur, "%d%*s", &dataint) <= 0) { 390: return FALSE; 391: } 392: analog->offset_time = dataint; 393: 394: strlcur = ptrpos += 1; 395: ptrpos = strchr(strlcur, ','); 396: if ((!ptrpos) || (ptrpos >= strlend)) { 397: return FALSE; 398: } 399: if (sscanf(strlcur, "%d%*s", &dataint) <= 0) { 400: return FALSE; 401: } 402: analog->smp_min = dataint; 403: 404: strlcur = ptrpos += 1; 405: if (ptrpos > strlend) { 406: return FALSE; 407: } 408: if (sscanf(strlcur, "%d%*s", &dataint) <= 0) { 409: return FALSE; 410: } 411: analog->smp_max = dataint; 412: 413: return TRUE; 414: } 415: 416: /* 417: * read_cmtr_cfg_one_digit - 分析一行数字量信息. 418: * @analog: 输出参数,数字量信息; 419: * @strline:输入参数,内容缓冲区; 420: * @size:输入参数,缓冲区大小; 421: * @strlend: 输入参数,读取的line结束指针; 422: * 423: * 返回TRUE成功,失败返回FALSE。 424: * 425: */ 426: static u8 read_cmtr_cfg_one_digit(struct cmtr_cfg_digit *digit, char *strline, int size, char *strlend) 427: { 428: int dataint = 0; 429: char* ptrpos = 0; 430: char* strlcur = strline; 431: ptrpos = strchr(strlcur, ','); 432: if ((!ptrpos) || (ptrpos >= strlend)) { 433: return FALSE; 434: } 435: if (sscanf(strlcur, "%d%*s", &dataint) <= 0) { 436: return FALSE; 437: } 438: digit->index = dataint; 439: 440: strlcur = ptrpos += 1; 441: ptrpos = strchr(strlcur, ','); 442: if ((!ptrpos) || (ptrpos >= strlend)) { 443: return FALSE; 444: } 445: memset(digit->name, '\0', CMTR_STRING_MAX_LENGTH); 446: memcpy(digit->name, strlcur, ptrpos-strlcur); 447: 448: strlcur = ptrpos += 1; 449: if (ptrpos > strlend) { 450: return FALSE; 451: } 452: if (sscanf(strlcur, "%d", &dataint) <= 0) { 453: return FALSE; 454: } 455: digit->state = dataint; 456: 457: return TRUE; 458: } 459: 460: /* 461: * read_cmtr_cfg_info - 读cmtr配置文件. 462: * @pfd: 输入输出参数,地址 463: * @cfg:输出参数,cmtr(cfg文件)结构体 464: * @counter: 输出参数,读取的字节计数器; 465: * 466: * 返回当前pfd指针,读失败返回NULL 467: * 468: */ 469: _my_cmtr_ioptr read_cmtr_cfg_info(_my_cmtr_ioptr pfd, struct cmtr_cfg_info *cfg, int* counter) 470: { 471: u8 returntag = FALSE; 472: 473: int strsize = 1024; 474: char* strline = NULL; 475: char* strlcur = NULL; 476: char* strlend = NULL; 477: _my_cmtr_ioptr curr_pfd = pfd; 478: 479: char* ptrpos = 0; 480: 481: int port1num = 0; 482: int port2num = 0; 483: char port1chr = '\0'; 484: char port2chr = '\0'; 485: 486: int index = 0; 487: int dataint = 0; 488: f32 dataflt = 0; 489: 490: _my_assert(pfd && cfg); 491: 492: strline = _my_buf_malloc(strsize); 493: memset(strline, '\0', strsize); 494: 495: /* read station name and kymograph id */ 496: curr_pfd = read_cmtr_cfg_line(curr_pfd, strline, strsize, &strlend, counter); 497: 498: if (!curr_pfd) { 499: goto RETURN_FINISH; 500: } 501: strlcur = strline; 502: ptrpos = strchr(strlcur, ','); 503: memset(cfg->station_name, '\0', CMTR_STRING_MAX_LENGTH); 504: memset(cfg->kymograph_id, '\0', CMTR_STRING_MAX_LENGTH); 505: if (ptrpos) { 506: memcpy(cfg->station_name, strlcur, ptrpos - strlcur); 507: if (ptrpos < strlend) { 508: ptrpos += 1; 509: memcpy(cfg->kymograph_id, ptrpos, strlen(ptrpos)); 510: } 511: } else { 512: memcpy(cfg->station_name, strlcur, strlen(strlcur)); 513: } 514: 515: /* read port count */ 516: curr_pfd = read_cmtr_cfg_line(curr_pfd, strline, strsize, &strlend, counter); 517: if (!curr_pfd) { 518: goto RETURN_FINISH; 519: } 520: strlcur = strline; 521: ptrpos = strchr(strlcur, ','); 522: if ((!ptrpos) || (ptrpos >= strlend)) { 523: goto RETURN_FINISH; 524: } 525: ptrpos += 1; 526: if (sscanf(ptrpos, "%d%c%*s", &port1num, &port1chr) <= 0) { 527: goto RETURN_FINISH; 528: } 529: ptrpos = strchr(ptrpos, ','); 530: if ((!ptrpos) || (ptrpos >= strlend)) { 531: goto RETURN_FINISH; 532: } 533: ptrpos += 1; 534: if (sscanf(ptrpos, "%d%c", &port2num, &port2chr) <= 0) { 535: goto RETURN_FINISH; 536: } 537: if ((port1chr == 'A') || (port1chr == 'a')) { 538: cfg->analog_count = port1num; 539: cfg->digit_count = port2num; 540: } else if ((port1chr == 'D') || (port1chr == 'd')) { 541: cfg->analog_count = port2num; 542: cfg->digit_count = port1num; 543: } else { 544: goto RETURN_FINISH; 545: } 546: 547: /* read analog port info */ 548: for (index = 0; index < cfg->analog_count; index++) { 549: curr_pfd = read_cmtr_cfg_line(curr_pfd, strline, strsize, &strlend, counter); 550: if (!curr_pfd) { 551: goto RETURN_FINISH; 552: } 553: if (!read_cmtr_cfg_one_analog((cfg->analogs)+index, strline, strsize, strlend)) { 554: goto RETURN_FINISH; 555: } 556: } 557: /* read digit port info */ 558: for (index = 0; index < cfg->digit_count; index++) { 559: curr_pfd = read_cmtr_cfg_line(curr_pfd, strline, strsize, &strlend, counter); 560: if (!curr_pfd) { 561: goto RETURN_FINISH; 562: } 563: if (!read_cmtr_cfg_one_digit((cfg->digits)+index, strline, strsize, strlend)) { 564: goto RETURN_FINISH; 565: } 566: } 567: 568: /* read Frequency info */ 569: curr_pfd = read_cmtr_cfg_line(curr_pfd, strline, strsize, &strlend, counter); 570: if (!curr_pfd) { 571: goto RETURN_FINISH; 572: } 573: if (strline > strlend) { 574: goto RETURN_FINISH; 575: } 576: if (sscanf(strline, "%f", &dataflt) <= 0) { 577: goto RETURN_FINISH; 578: } 579: cfg->frequency = dataflt; 580: 581: /* read smprate count info */ 582: curr_pfd = read_cmtr_cfg_line(curr_pfd, strline, strsize, &strlend, counter); 583: if (!curr_pfd) { 584: goto RETURN_FINISH; 585: } 586: if (strline > strlend) { 587: goto RETURN_FINISH; 588: } 589: if (sscanf(strline, "%d", &dataint) <= 0) { 590: goto RETURN_FINISH; 591: } 592: cfg->smprate_count = dataint; 593: 594: /* read smprate info */ 595: for (index = 0; index < cfg->smprate_count; index ++) { 596: curr_pfd = read_cmtr_cfg_line(curr_pfd, strline, strsize, &strlend, counter); 597: if (!curr_pfd) { 598: goto RETURN_FINISH; 599: } 600: strlcur = strline; 601: ptrpos = strchr(strlcur, ','); 602: if ((!ptrpos) || (ptrpos >= strlend)) { 603: goto RETURN_FINISH; 604: } 605: if (sscanf(strlcur, "%f%*s", &dataflt) <= 0) { 606: goto RETURN_FINISH; 607: } 608: cfg->smprates[index].rate = dataflt; 609: strlcur = ptrpos += 1; 610: if (ptrpos > strlend) { 611: goto RETURN_FINISH; 612: } 613: if (sscanf(strlcur, "%d", &dataint) <= 0) { 614: goto RETURN_FINISH; 615: } 616: cfg->smprates[index].point = dataint; 617: } 618: 619: /* read time info */ 620: curr_pfd = read_cmtr_cfg_line(curr_pfd, strline, strsize, &strlend, counter); 621: if (!curr_pfd) { 622: goto RETURN_FINISH; 623: } 624: memset(cfg->begin_time, '\0', CMTR_STRING_MAX_LENGTH); 625: if (strlend - strline >= 0) { 626: memcpy(cfg->begin_time, strline, strlend - strline + 1); 627: } 628: curr_pfd = read_cmtr_cfg_line(curr_pfd, strline, strsize, &strlend, counter); 629: if (!curr_pfd) { 630: goto RETURN_FINISH; 631: } 632: memset(cfg->end_time, '\0', CMTR_STRING_MAX_LENGTH); 633: if (strlend - strline >= 0) { 634: memcpy(cfg->end_time, strline, strlend - strline + 1); 635: } 636: 637: /* read dat type info */ 638: curr_pfd = read_cmtr_cfg_line(curr_pfd, strline, strsize, &strlend, counter); 639: if (!curr_pfd) { 640: goto RETURN_FINISH; 641: } 642: strlcur =_my_strupr(strline); 643: ptrpos = strstr(strlcur, "BIN"); 644: memset(cfg->file_type, '\0', CMTR_STRING_MAX_LENGTH); 645: if (ptrpos > 0) { 646: strcpy(cfg->file_type, "BINARY"); 647: } else if (strstr(strlcur, "ASC") > 0) { 648: strcpy(cfg->file_type, "ASCII"); 649: } 650: else { 651: goto RETURN_FINISH; 652: } 653: 654: returntag = TRUE; 655: 656: RETURN_FINISH: 657: _my_buf_free(strline); 658: return returntag ? curr_pfd : NULL; 659: } 660: 661: /* 662: * read_cmtr_dat_smpdot_binary - 读bin格式cmtr采样点数据信息. 663: * @pfd: 输入输出参数,地址 664: * @big_endian_tag: 输入参数,标识文件中数据的字节顺序,为FALSE按照小端读(默认值),True按照大端读; 665: * @analog_count: 输入参数,模拟量个数; 666: * @digit_count: 输入参数,数字量个数; 667: * @dot: 输出参数,采样点信息; 668: * @the_smp_mins: 输出参数,统计最小值,为数组,个数至少为analog_count个,值为NULL时忽略统计; 669: * @the_smp_maxs: 输出参数,统计最大值,为数组,个数至少为analog_count个,值为NULL时忽略统计; 670: * @counter: 输出参数,读取的字节计数器; 671: * 672: * 返回当前pfd指针,读失败返回NULL 673: * 674: */ 675: _my_cmtr_ioptr read_cmtr_dat_smpdot_binary(_my_cmtr_ioptr pfd, u8 big_endian_tag, 676: int analog_count, int digit_count, 677: struct cmtr_dat_smpdot *dot, 678: u32* the_smp_mins, u32* the_smp_maxs, 679: int* counter) 680: { 681: u16 data16 = 0x00; 682: u32 data32 = 0x00; 683: int oldnum = 0; 684: 685: int index = 0; 686: int bitpos = 0; 687: 688: _my_cmtr_ioptr curr_pfd = pfd; 689: 690: oldnum = (*counter); 691: data32 = 0x00; 692: _my_read_cmtr_data(curr_pfd, &data32, 4, *counter); 693: if ((*counter) <= oldnum) { 694: return NULL; 695: } 696: dot->index = big_endian_tag ? _my_btoh32(data32) : _my_ltoh32(data32); 697: 698: oldnum = (*counter); 699: data32 = 0x00; 700: _my_read_cmtr_data(curr_pfd, &data32, 4, *counter); 701: if ((*counter) <= oldnum) { 702: return NULL; 703: } 704: dot->time = big_endian_tag ? _my_btoh32(data32) : _my_ltoh32(data32); 705: 706: /* read analog port info */ 707: for (index = 0; index < analog_count; index ++) { 708: oldnum = (*counter); 709: data16 = 0x00; 710: _my_read_cmtr_data(curr_pfd, &data16, 2, *counter); 711: if ((*counter) <= oldnum) { 712: return NULL; 713: } 714: dot->analogs[index] = big_endian_tag ? _my_btoh16(data16) : _my_ltoh16(data16); 715: if (the_smp_mins) { 716: if (the_smp_mins + index) { 717: the_smp_mins[index] = _my_min(the_smp_mins[index], dot->analogs[index]); 718: } 719: } 720: if (the_smp_maxs) { 721: if (the_smp_maxs + index) { 722: the_smp_maxs[index] = _my_min(the_smp_maxs[index], dot->analogs[index]); 723: } 724: } 725: } 726: /* read digit port info */ 727: for (index = 0; index < digit_count; index ++) { 728: oldnum = (*counter); 729: data16 = 0x00; 730: _my_read_cmtr_data(curr_pfd, &data16, 2, *counter); 731: if ((*counter) <= oldnum) { 732: return NULL; 733: } 734: data16 = big_endian_tag ? _my_btoh16(data16) : _my_ltoh16(data16); 735: for (bitpos = 0; bitpos < 16; bitpos++) { 736: if ((index * 16 + bitpos) < digit_count) { 737: dot->digits[index * 16 + bitpos] = (data16 & (0x0001 << bitpos)); 738: } else { 739: break; 740: } 741: } 742: } 743: 744: return curr_pfd; 745: } 746: 747: /* 748: * read_cmtr_dat_smpdot_ascii - 读ascii格式cmtr采样点数据信息. 749: * @pfd: 输入输出参数,地址 750: * @read_buf: 输入参数,读缓冲,在外部申请内存,避免在内部频繁申请、释放内存; 751: * @buf_size: 输入参数,读缓冲区的大小; 752: * @analog_count: 输入参数,模拟量个数; 753: * @digit_count: 输入参数,数字量个数; 754: * @dot: 输出参数,采样点信息; 755: * @the_smp_mins: 输出参数,统计最小值,为数组,个数至少为analog_count个,值为NULL时忽略统计; 756: * @the_smp_maxs: 输出参数,统计最大值,为数组,个数至少为analog_count个,值为NULL时忽略统计; 757: * @counter: 输出参数,读取的字节计数器; 758: * 759: * 返回当前pfd指针,读失败返回NULL 760: * 761: */ 762: _my_cmtr_ioptr read_cmtr_dat_smpdot_ascii(_my_cmtr_ioptr pfd, 763: u8 *read_buf, int buf_size, 764: int analog_count, int digit_count, 765: struct cmtr_dat_smpdot *dot, 766: u16* the_smp_mins,u16* the_smp_maxs, 767: int* counter) 768: { 769: char* ptrpos = 0; 770: char* strlend = 0; 771: 772: int index = 0; 773: 774: int dataint = 0; 775: float dataflt = 0; 776: 777: _my_cmtr_ioptr curr_pfd = pfd; 778: 779: memset(read_buf, '\0', buf_size); 780: curr_pfd = read_cmtr_cfg_line(curr_pfd, read_buf, buf_size, &strlend, counter); 781: if (!curr_pfd) { 782: return NULL; 783: } 784: 785: ptrpos = read_buf; 786: if ((!ptrpos) || (ptrpos >= strlend)) { 787: return NULL; 788: } 789: if (sscanf(ptrpos, "%d%*s", &dataint) <= 0) { 790: return NULL; 791: } 792: dot->index = dataint; 793: ptrpos = strchr(ptrpos, ','); 794: if (!ptrpos) { 795: return NULL; 796: } 797: ptrpos += 1; 798: if ((!ptrpos) || (ptrpos > strlend)) { 799: return NULL; 800: } 801: if (sscanf(ptrpos, "%d%*s", &dataint) <= 0) { 802: return NULL; 803: } 804: dot->time = dataint; 805: 806: /* read analog port info */ 807: for (index = 0; index < analog_count; index ++) { 808: ptrpos = strchr(ptrpos, ','); 809: if (!ptrpos) { 810: return NULL; 811: } 812: ptrpos += 1; 813: if ((!ptrpos) || (ptrpos > strlend)) { 814: return NULL; 815: } 816: if (sscanf(ptrpos, "%f%*s", &dataflt) <= 0) { 817: return NULL; 818: } 819: dot->analogs[index] = dataflt; 820: if (the_smp_mins) { 821: if (the_smp_mins + index) { 822: the_smp_mins[index] = _my_min(the_smp_mins[index], dataflt); 823: } 824: } 825: if (the_smp_maxs) { 826: if (the_smp_maxs + index) { 827: the_smp_maxs[index] = _my_min(the_smp_maxs[index], dataflt); 828: } 829: } 830: } 831: /* read digit port info */ 832: for (index = 0; index < digit_count; index ++) { 833: ptrpos = strchr(ptrpos, ','); 834: if (!ptrpos) { 835: return NULL; 836: } 837: ptrpos += 1; 838: if ((!ptrpos) || (ptrpos > strlend)) { 839: return NULL; 840: } 841: if (sscanf(ptrpos, "%d%*s", &dataint) <= 0) { 842: return NULL; 843: } 844: dot->digits[index] = dataint; 845: } 846: 847: return curr_pfd; 848: } 849: 850: /* 851: * print_cmtr_cfg_info - 打印cmtr文件配置数. 852: * @cfg: 输入参数,cmtr文件配置数据; 853: * 854: */ 855: void print_cmtr_cfg_info(struct cmtr_cfg_info *cfg) 856: { 857: u32 index = 0; 858: if ( cfg ) { 859: _my_printf("=====================\n"); 860: _my_printf("%s,%s\n", cfg->station_name, cfg->kymograph_id); 861: _my_printf("%d,%dA,%dD\n", cfg->analog_count + cfg->digit_count, cfg->analog_count, cfg->digit_count); 862: for (index = 0; index < cfg->analog_count; index++) { 863: _my_printf("%d,%s,%s,%s,%s,%.6lf,%.6lf,%d,%d,%d\n", 864: cfg->analogs[index].index, 865: cfg->analogs[index].name, 866: cfg->analogs[index].phase, 867: cfg->analogs[index].element, 868: cfg->analogs[index].unit, 869: cfg->analogs[index].factor_a, 870: cfg->analogs[index].factor_b, 871: cfg->analogs[index].offset_time, 872: cfg->analogs[index].smp_min, 873: cfg->analogs[index].smp_max); 874: } 875: for (index = 0; index < cfg->digit_count; index++) { 876: _my_printf("%d,%s,%d\n", 877: cfg->digits[index].index, 878: cfg->digits[index].name, 879: cfg->digits[index].state); 880: } 881: _my_printf("%.6f\n", cfg->frequency); 882: for (index = 0; index < cfg->smprate_count; index++) { 883: _my_printf("%f,%d\n", cfg->smprates[index].rate, cfg->smprates[index].point); 884: } 885: _my_printf("%s\n", cfg->begin_time); 886: _my_printf("%s\n", cfg->end_time); 887: _my_printf("%s\n", cfg->file_type); 888: _my_printf("=====================\n"); 889: } 890: } 891: 892: /* 893: * print_cmtr_dat_smpdot - 打印cmtr数据文件采样点. 894: * @cfg: 输入参数,cmtr文件配置数据; 895: * @analog_count: 输入参数,模拟量个数; 896: * @digit_count: 输入参数,数字量个数; 897: * @dot: 输入参数,采样点信息; 898: * 899: */ 900: void print_cmtr_dat_smpdot(int analog_count, int digit_count, struct cmtr_dat_smpdot *dot) 901: { 902: int index = 0; 903: if ( dot ) { 904: _my_printf("%u,%d", dot->index, dot->time); 905: for (index = 0; index < analog_count; index++) { 906: _my_printf(",%d", dot->analogs[index]); 907: } 908: for (index = 0; index < digit_count; index++) { 909: _my_printf(",%d", dot->digits[index]); 910: } 911: _my_printf("\n"); 912: } 913: } 914: 915: 916: #ifdef CMTR_CONSOLE_DEMO 917: 918: 919: /* 920: * _my_cmtr_openrb/_my_cmtr_openwb/_my_cmtr_openab/_my_cmtr_close 921: * - 可以根据需要改写该接口,如重定义为网口的recv\send、串口r\w等 922: * @pfd: 文件地址、缓冲区地址、或者socket地址等 923: * @str: 文件路径或者联机ip或者串口地址或者共享内存名称 924: * 925: */ 926: #define _my_cmtr_openrb(str) (open((str), O_RDONLY, S_IWRITE | S_IREAD)) 927: #define _my_cmtr_openwb(str) (open((str), O_CREAT | O_RDWR, S_IWRITE | S_IREAD)) 928: #define _my_cmtr_openab(str) (open((str), O_CREAT | O_APPEND | O_RDWR, S_IWRITE | S_IREAD)) 929: #define _my_cmtr_close(pfd) (close(pfd)) 930: 931: 932: /* 933: * cmtr_test_demo - 测试函数 934: * 935: */ 936: 937: void cmtr_test_demo() 938: { 939: int counter1 = 0; 940: int counter2 = 0; 941: struct cmtr_dat_smpdot dot0; 942: struct cmtr_cfg_info cfg0; 943: _my_cmtr_ioptr fdcfg1 = 0; 944: _my_cmtr_ioptr fddat1 = 0; 945: _my_cmtr_ioptr fdcfg2 = 0; 946: _my_cmtr_ioptr fddat2 = 0; 947: int buf_size = 1024; 948: u8 *read_buf = _my_buf_malloc(buf_size); 949: int analog_count = 0; 950: int digit_count = 0; 951: u16 *the_smp_mins = 0; 952: u16 *the_smp_maxs = 0; 953: 954: fdcfg1 = _my_cmtr_openrb("E:/iec-61850/test_r.cfg"); 955: fdcfg2 = _my_cmtr_openwb("E:/iec-61850/test_w.cfg"); 956: _my_assert(fdcfg1); 957: _my_assert(fdcfg2); 958: read_cmtr_cfg_info(fdcfg1, &cfg0, &counter1); 959: print_cmtr_cfg_info(&cfg0); 960: write_cmtr_cfg_info(fdcfg2, &cfg0, &counter2); 961: _my_cmtr_close(fdcfg1); 962: _my_cmtr_close(fdcfg2); 963: 964: 965: fddat1 = _my_cmtr_openrb("E:/iec-61850/test_r.dat"); 966: fddat2 = _my_cmtr_openwb("E:/iec-61850/test_w.dat"); 967: while (_my_check_cmtr_ptr(fddat1)) { 968: analog_count = cfg0.analog_count; 969: digit_count = cfg0.digit_count; 970: if (analog_count > 0) the_smp_mins = _my_buf_malloc(2*analog_count); 971: if (analog_count > 0) the_smp_maxs = _my_buf_malloc(2*analog_count); 972: fddat1 = read_cmtr_dat_smpdot_ascii(fddat1, 973: read_buf, buf_size, 974: analog_count, digit_count, 975: &dot0, 976: the_smp_mins, the_smp_maxs, 977: &counter1); 978: if (_my_check_cmtr_ptr(fddat1)) { 979: print_cmtr_dat_smpdot(analog_count, digit_count, &dot0); 980: fddat2 = write_cmtr_dat_smpdot_ascii(fddat2, analog_count, digit_count, &dot0, &counter2); 981: } 982: } 983: _my_cmtr_close(fddat1); 984: _my_cmtr_close(fddat2); 985: } 986: 987: 988: /* 989: * main - 测试main函数 990: * 991: */ 992: int main(int argc, char* argv[]) 993: { 994: cmtr_test_demo(); 995: getchar(); 996: return 0; 997: } 998: 999: 1000: #endif /* CMTR_CONSOLE_DEMO */ 1001:
09-05
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值