📄 events.c
字号:
// ----------------------------------------------------------------------------// Copyright 2006-2007, Martin D. Flynn// All rights reserved// ----------------------------------------------------------------------------//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// // http://www.apache.org/licenses/LICENSE-2.0// // Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.//// ----------------------------------------------------------------------------// Description:// GPS/Data event manager. // Generates and manages events.// ---// Change History:// 2006/01/04 Martin D. Flynn// -Initial release// 2006/06/08 Martin D. Flynn// -Populate gpsPDOP in 'evSetEventGPS'// 2007/01/28 Martin D. Flynn// -WindowsCE port// -Added custom fields FIELD_ENTITY, FIELD_OBC_DISTANCE// -Limit temperatures to +/-126 for LO_RES, and +/-3276.6 for HI_RES// -Changed to support elapsed time resolution of 1 second// -Added field support for OBC fields// 2007/02/11 Martin D. Flynn// -Added FIELD_OBC_COOLANT_LEVEL, FIELD_OBC_OIL_PRESSURE// -Changed FIELD_OBC_ENGINE_TEMP to FIELD_OBC_COOLANT_TEMP and added hiRes mode// 2007/02/25 Martin D. Flynn// -Changed 'FIELD_OBC_FAULT_CODE' to 'FIELD_OBC_J1708_FAULT'// -Changed 'obcFaultCode' to 'obcJ1708Fault'// 2007/03/11 Martin D. Flynn// -Added support for 'FIELD_OBC_FUEL_USED'// ----------------------------------------------------------------------------#include "stdafx.h" // TARGET_WINCE#include "custom/defaults.h"#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <ctype.h>#include <time.h>//#include <sys/time.h>#include "custom/log.h"#include "tools/stdtypes.h"#include "tools/bintools.h"#include "tools/strtools.h"#include "tools/utctools.h"#include "base/propman.h"#include "base/pqueue.h"#include "base/event.h"#include "base/events.h"// ----------------------------------------------------------------------------#define TEMPERATURE_LO_RES_INVALID 127L // 1 byte#define TEMPERATURE_HI_RES_INVALID 32767L // 2 bytes// ----------------------------------------------------------------------------PacketQueue_DEFINE(eventQueue,EVENT_QUEUE_SIZE);static UInt32 eventSequence = 0L;static UInt32 totalPacketCount = 0L;// ----------------------------------------------------------------------------/* define standard resolution fixed packet type */static FieldDef_t FixedFields_30[] = { EVENT_FIELD(FIELD_STATUS_CODE , LO_RES, 0, 2), EVENT_FIELD(FIELD_TIMESTAMP , LO_RES, 0, 4), EVENT_FIELD(FIELD_GPS_POINT , LO_RES, 0, 6), EVENT_FIELD(FIELD_SPEED , LO_RES, 0, 1), EVENT_FIELD(FIELD_HEADING , LO_RES, 0, 1), EVENT_FIELD(FIELD_ALTITUDE , LO_RES, 0, 2), EVENT_FIELD(FIELD_DISTANCE , LO_RES, 0, 3), EVENT_FIELD(FIELD_SEQUENCE , LO_RES, 0, 1),};static CustomDef_t FixedPacket_30 = { PKT_CLIENT_FIXED_FMT_STD, (sizeof(FixedFields_30)/sizeof(FixedFields_30[0])), FixedFields_30};/* define high resolution fixed packet type */static FieldDef_t FixedFields_31[] = { EVENT_FIELD(FIELD_STATUS_CODE , HI_RES, 0, 2), EVENT_FIELD(FIELD_TIMESTAMP , HI_RES, 0, 4), EVENT_FIELD(FIELD_GPS_POINT , HI_RES, 0, 8), EVENT_FIELD(FIELD_SPEED , HI_RES, 0, 2), EVENT_FIELD(FIELD_HEADING , HI_RES, 0, 2), EVENT_FIELD(FIELD_ALTITUDE , HI_RES, 0, 3), EVENT_FIELD(FIELD_DISTANCE , HI_RES, 0, 3), EVENT_FIELD(FIELD_SEQUENCE , HI_RES, 0, 1),};static CustomDef_t FixedPacket_31 = { PKT_CLIENT_FIXED_FMT_HIGH, (sizeof(FixedFields_31)/sizeof(FixedFields_31[0])), FixedFields_31};/* table of predefined formats */static CustomDef_t *FixedEventTable[] = { &FixedPacket_30, // standard resolution &FixedPacket_31 // high resolution};// ----------------------------------------------------------------------------/* table of custom formats */static CustomDef_t *CustomEventTable[] = { (CustomDef_t*)0, (CustomDef_t*)0, (CustomDef_t*)0, (CustomDef_t*)0, (CustomDef_t*)0};// ----------------------------------------------------------------------------/* add a custom format field definition */// This should be done at startup initializationutBool evAddCustomDefinition(CustomDef_t *cd){ int i, maxSize; maxSize = sizeof(CustomEventTable)/sizeof(CustomEventTable[0]); for (i = 0; i < maxSize; i++) { if (!CustomEventTable[i]) { CustomEventTable[i] = cd; return utTrue; } } return utFalse;}// ----------------------------------------------------------------------------static CustomDef_t *_evGetCustomDefinitionForType(ClientPacketType_t hdrType){ int i, maxSize; /* first check fixed formats */ maxSize = sizeof(FixedEventTable)/sizeof(FixedEventTable[0]); for (i = 0; (i < maxSize) && FixedEventTable[i]; i++) { if (hdrType == FixedEventTable[i]->hdrType) { return FixedEventTable[i]; } } /* check custom formats */ maxSize = sizeof(CustomEventTable)/sizeof(CustomEventTable[0]); for (i = 0; (i < maxSize) && CustomEventTable[i]; i++) { if (hdrType == CustomEventTable[i]->hdrType) { return CustomEventTable[i]; } } /* still not found */ return (CustomDef_t*)0;}/* return a 'template' packet for the specified custom type */utBool evGetCustomFormatPacket(Packet_t *pkt, ClientPacketType_t cstPktType){ CustomDef_t *custDef = _evGetCustomDefinitionForType(cstPktType); if (custDef) { int i; /* custom format packet type */ ClientPacketType_t fmtType = PKT_CLIENT_FORMAT_DEF_24; /* assemble packet */ int rtn = pktInit(pkt, fmtType, (char*)0); if (rtn >= 0) { FmtBuffer_t bb, *bf = pktFmtBuffer(&bb, pkt); binFmtPrintf(bf, "%1x%1u", (UInt32)CLIENT_PACKET_TYPE(custDef->hdrType), (UInt32)custDef->fldLen); for (i = 0; i < custDef->fldLen; i++) { FieldDef_t *f = &(custDef->fld[i]); UInt32 fldDef = FIELD_DEF24(f); binFmtPrintf(bf, "%3x", fldDef); } pkt->dataLen = (UInt8)BUFFER_DATA_LENGTH(bf); return utTrue; } else { logERROR(LOGSRC,"Packet buffer overflow"); return utFalse; } } return utFalse;}// ----------------------------------------------------------------------------static Int32 _round(double D) { return (D>=0.0)?(Int32)(D+0.5):(Int32)(D-0.5); }#define ROUND(D) _round(D) // ((UInt32)((D) + 0.5))#define LIMIT_INDEX(N,L) (((N) >= (L))? ((L) - 1) : (N))/* create Packet from Event structure */static Packet_t *_evCreateEventPacket(Packet_t *pkt, ClientPacketType_t pktType, CustomDef_t *custDef, UInt32 *evtSeq, Event_t *er){ UInt8 fldLen = (UInt8)custDef->fldLen; FieldDef_t *fld = custDef->fld; /* init packet */ pktInit(pkt, pktType, (char*)0); // payload filled-in below /* binPrintf format buffer */ FmtBuffer_t bb, *bf = pktFmtBuffer(&bb, pkt); /* cache sequence number */ UInt32 sequence = SEQUENCE_ALL; UInt8 seqPos = 0, seqLen = 0; // unspecified /* fill in custom fields */ int i; for (i = 0; i < fldLen; i++) { int len = (int)fld[i].length; UInt8 ndx = (UInt8)fld[i].index; utBool isHiRes = fld[i].hiRes; Int32 iVal32 = 0L; UInt32 uVal32 = 0L; char *fmt = ""; switch ((EventFieldType_t)fld[i].type) { case FIELD_STATUS_CODE : // hex // 'len' had better be '2' (however, no checking is made at this point) binFmtPrintf(bf, "%*x", len, (UInt32)er->statusCode); break; case FIELD_TIMESTAMP : // 'len' had better be '4' (however, no checking is made at this point) ndx = LIMIT_INDEX(ndx, sizeof(er->timestamp)/sizeof(er->timestamp[0])); binFmtPrintf(bf, "%*u", len, (UInt32)er->timestamp[ndx]); break; case FIELD_INDEX : binFmtPrintf(bf, "%*u", len, (UInt32)er->index); break; case FIELD_GPS_POINT : // 'len' had better be '6' or '8' (however, no checking is made at this point) ndx = LIMIT_INDEX(ndx, sizeof(er->gpsPoint)/sizeof(er->gpsPoint[0])); binFmtPrintf(bf, "%*g", len, &(er->gpsPoint[ndx])); break; case FIELD_GPS_AGE : if ((len == 1) && (er->gpsAge > 0xFF)) { binFmtPrintf(bf, "%*u", len, (UInt32)0xFF); } else if ((len == 2) && (er->gpsAge > 0xFFFF)) { binFmtPrintf(bf, "%*u", len, (UInt32)0xFFFF); } else { binFmtPrintf(bf, "%*u", len, (UInt32)er->gpsAge); } break; case FIELD_SPEED : // double uVal32 = isHiRes? (UInt32)ROUND(er->speedKPH * 10.0) : (UInt32)ROUND(er->speedKPH); binFmtPrintf(bf, "%*u", len, uVal32); break; case FIELD_HEADING : // double uVal32 = isHiRes? (UInt32)ROUND(er->heading * 100.0) : (UInt32)ROUND(er->heading * 255.0/360.0); fmt = isHiRes? "%*u" : "%*x"; binFmtPrintf(bf, fmt, len, uVal32); break; case FIELD_ALTITUDE : // double +/- iVal32 = isHiRes? (Int32)ROUND(er->altitude * 10.0) : (Int32)ROUND(er->altitude); binFmtPrintf(bf, "%*i", len, iVal32); break; case FIELD_DISTANCE : // double uVal32 = isHiRes? (UInt32)ROUND(er->distanceKM * 10.0) : (UInt32)ROUND(er->distanceKM); binFmtPrintf(bf, "%*u", len, uVal32); break; case FIELD_ODOMETER : // double uVal32 = isHiRes? (UInt32)ROUND(er->odometerKM * 10.0) : (UInt32)ROUND(er->odometerKM); binFmtPrintf(bf, "%*u", len, uVal32); break; case FIELD_SEQUENCE : // hex (UInt32) seqPos = (UInt8)BUFFER_DATA_INDEX(bf); seqLen = (UInt8)len; sequence = evtSeq? (((*evtSeq)++) & SEQUENCE_MASK(len)) : 0L; binFmtPrintf(bf, "%*x", len, (UInt32)sequence); break; case FIELD_GEOFENCE_ID : // hex (UInt32) ndx = LIMIT_INDEX(ndx, sizeof(er->geofenceID)/sizeof(er->geofenceID[0])); binFmtPrintf(bf, "%*x", len, (UInt32)er->geofenceID[ndx]); break; case FIELD_TOP_SPEED : // double uVal32 = isHiRes? (UInt32)ROUND(er->topSpeedKPH * 10.0) : (UInt32)ROUND(er->topSpeedKPH); binFmtPrintf(bf, "%*u", len, uVal32); break;#ifdef EVENT_INCL_STRING case FIELD_STRING : ndx = LIMIT_INDEX(ndx, sizeof(er->string)/sizeof(er->string[0])); binFmtPrintf(bf, "%*s", len, er->string[ndx]); break; case FIELD_STRING_PAD : ndx = LIMIT_INDEX(ndx, sizeof(er->string)/sizeof(er->string[0])); binFmtPrintf(bf, "%*p", len, er->string[ndx]); break;#endif#ifdef EVENT_INCL_ENTITY case FIELD_ENTITY : ndx = LIMIT_INDEX(ndx, sizeof(er->entity)/sizeof(er->entity[0])); binFmtPrintf(bf, "%*s", len, er->entity[ndx]); break; case FIELD_ENTITY_PAD : ndx = LIMIT_INDEX(ndx, sizeof(er->entity)/sizeof(er->entity[0])); binFmtPrintf(bf, "%*p", len, er->entity[ndx]); break;#endif#ifdef EVENT_INCL_BINARY case FIELD_BINARY : if (er->binary) { if (len <= er->binaryLen) { binFmtPrintf(bf, "%*b", len, er->binary); } else { binFmtPrintf(bf, "%*b%*z", er->binaryLen, er->binary, len - er->binaryLen); } } else { binFmtPrintf(bf, "%*z", len); } break;#endif#ifdef EVENT_INCL_DIGITAL_INPUT case FIELD_INPUT_ID : // hex binFmtPrintf(bf, "%*x", len, (UInt32)er->inputID); break; case FIELD_INPUT_STATE : // hex binFmtPrintf(bf, "%*x", len, (UInt32)er->inputState); break; case FIELD_OUTPUT_ID : // hex binFmtPrintf(bf, "%*x", len, (UInt32)er->outputID); break; case FIELD_OUTPUT_STATE : // hex binFmtPrintf(bf, "%*x", len, (UInt32)er->outputState); break; case FIELD_ELAPSED_TIME : ndx = LIMIT_INDEX(ndx, sizeof(er->elapsedTimeSec)/sizeof(er->elapsedTimeSec[0])); binFmtPrintf(bf, "%*u", len, (UInt32)er->elapsedTimeSec[ndx]); break; case FIELD_COUNTER : ndx = LIMIT_INDEX(ndx, sizeof(er->counter)/sizeof(er->counter[0])); binFmtPrintf(bf, "%*u", len, (UInt32)er->counter[ndx]); break;#endif#ifdef EVENT_INCL_ANALOG_INPUT case FIELD_SENSOR32_LOW : ndx = LIMIT_INDEX(ndx, sizeof(er->sensor32LO)/sizeof(er->sensor32LO[0])); binFmtPrintf(bf, "%*u", len, (UInt32)er->sensor32LO[ndx]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -