📄 propman.c
字号:
kv->lenNdx = 0; // data is now empty kv->dataSize = 0; kv->attr |= KVA_NONDEFAULT; kv->attr |= KVA_CHANGED; return PROP_ERROR_OK; } else { KeyData_t *keyDataBuf = _propGetData(kv); UInt16 keyDataSiz = _propGetDataCapacity(kv); int type = KVT_TYPE(kv->type), maxBpe = 0, len = 0; switch (type) { case KVT_UINT8: case KVT_UINT16: case KVT_UINT24: case KVT_UINT32: maxBpe = KVT_UINT_SIZE(type); // bytes per type if ((dataLen >= (kv->maxNdx * maxBpe)) || ((dataLen % kv->maxNdx) == 0)) { int n, bpe = dataLen / kv->maxNdx; if (bpe > maxBpe) { bpe = maxBpe; } // max bytes per element for (n = 0; n < kv->maxNdx; n++) { UInt32 val = binDecodeInt32(&data[n * bpe], bpe, KVT_IS_SIGNED(kv->type)); keyDataBuf->i[n] = val; } kv->lenNdx = kv->maxNdx; kv->dataSize = dataLen; kv->attr |= KVA_NONDEFAULT; kv->attr |= KVA_CHANGED; return PROP_ERROR(PROP_ERROR_OK, (kv->lenNdx * bpe)); } else { // invalid data length return PROP_ERROR_INVALID_LENGTH; } case KVT_BINARY: kv->lenNdx = (dataLen < keyDataSiz)? dataLen : keyDataSiz; kv->dataSize = kv->lenNdx; logINFO(LOGSRC,"Binary length: %lu", (UInt32)kv->lenNdx); if ((void*)data != (void*)keyDataBuf) { memset((void*)keyDataBuf, 0, keyDataSiz); memcpy((void*)keyDataBuf, (void*)data, kv->lenNdx); } kv->attr |= KVA_NONDEFAULT; kv->attr |= KVA_CHANGED; return PROP_ERROR(PROP_ERROR_OK, kv->lenNdx); case KVT_STRING: // _propSetValue // 'data' may, or may not, be terminated len = (dataLen < (keyDataSiz - 1))? dataLen : (keyDataSiz - 1); strncpy((char*)keyDataBuf->b, (char*)data, len); // strlen may be < len if 'data' was terminated keyDataBuf->b[len] = 0; // make sure it's terminated (however, data _may_ include terminator) kv->lenNdx = 1; // a string has been defined kv->dataSize = len; // not including terminating null kv->attr |= KVA_NONDEFAULT; kv->attr |= KVA_CHANGED; return PROP_ERROR(PROP_ERROR_OK, strlen((char*)keyDataBuf->b)); case KVT_GPS: // _propSetValue (binary format) len = _propDecodeGPS(&(keyDataBuf->gps), data, dataLen); if (len >= 0) { kv->dataSize = len; kv->lenNdx = 1; // GPS defined kv->attr |= KVA_NONDEFAULT; kv->attr |= KVA_CHANGED; return PROP_ERROR(PROP_ERROR_OK, len); } else { // invalid length return PROP_ERROR_INVALID_LENGTH; } break; } } // unsupported type return PROP_ERROR_INVALID_TYPE;} // _propSetValue/* set the key value to the specified bytes (from the server) */// This function obeys the 'KVA_IS_READONLY' flag.PropertyError_t propSetValueCmd(int protoNdx, Key_t key, const UInt8 *data, int dataLen){ KeyValue_t *kv = (KeyValue_t*)0;#if defined(SECONDARY_SERIAL_TRANSPORT) if ((key == PROP_STATE_DEVICE_ID) && (protoNdx == 1)) { kv = propGetKeyValueEntry(PROP_STATE_DEVICE_BT); } else { kv = propGetKeyValueEntry(key); }#else kv = propGetKeyValueEntry(key);#endif if (kv) { if (KVA_IS_READONLY(kv->attr)) { // cannot set a read-only property return PROP_ERROR_READ_ONLY; } else if (KVT_TYPE(kv->type) == KVT_COMMAND) { KeyData_t *keyDataBuf = _propGetData(kv); UInt16 keyDataSiz = _propGetDataCapacity(kv); if (keyDataBuf->cmd && (keyDataSiz >= sizeof(keyDataBuf->cmd))) { CommandError_t err; PROP_LOCK { err = (*keyDataBuf->cmd)(protoNdx, key, data, dataLen); } PROP_UNLOCK if (err == COMMAND_OK) { return PROP_ERROR_OK; } else if (err == COMMAND_OK_ACK) { return PROP_ERROR(PROP_ERROR_COMMAND_ERROR,err); } else { return PROP_ERROR(PROP_ERROR_COMMAND_ERROR,err); } } else { // the command has not been initialized (internal error) logERROR(LOGSRC,"Command not initialized: 0x%04X", (int)key); return PROP_ERROR_COMMAND_INVALID; } } else { PropertyError_t err; PROP_LOCK { err = _propSetValue(kv, data, dataLen); if (PROP_ERROR_OK_LENGTH(err) >= 0) { _propRefresh(PROP_REFRESH_SET, kv, (UInt8*)0, 0); } } PROP_UNLOCK return err; // length, or <0 if error } } else { return PROP_ERROR_INVALID_KEY; }}// ----------------------------------------------------------------------------/* get the byte array data for the KeyValue entry */static PropertyError_t _propGetValue(KeyValue_t *kv, FmtBuffer_t *bf){ if (KVA_IS_WRITEONLY(kv->attr)) { return PROP_ERROR_WRITE_ONLY; } else if (KVT_TYPE(kv->type) == KVT_COMMAND) { // should not be here (pre-validated) return PROP_ERROR_WRITE_ONLY; } else if (!BUFFER_DATA(bf) || (BUFFER_DATA_SIZE(bf) <= 0)) { // no place to put the data return PROP_ERROR_OK; // return ok anyway } else { KeyData_t *keyDataBuf = _propGetData(kv); UInt16 keyDataSiz = _propGetDataCapacity(kv); int type = KVT_TYPE(kv->type), maxBpe = 0; int len = 0; if (bf->fmt && (bf->fmtLen > 0)) { *bf->fmt = 0; /* init format */ } switch (type) { case KVT_UINT8: case KVT_UINT16: case KVT_UINT24: case KVT_UINT32: maxBpe = KVT_UINT_SIZE(type); // bytes per type if ((BUFFER_DATA_SIZE(bf) >= (kv->maxNdx * maxBpe)) || ((BUFFER_DATA_SIZE(bf) % kv->maxNdx) == 0)) { utBool isSigned = KVT_IS_SIGNED(kv->type); char fmtCh = isSigned? 'i' : (KVT_IS_HEX(kv->type)? 'x' : 'u'); int n, bpe = BUFFER_DATA_SIZE(bf) / kv->maxNdx; if (bpe > maxBpe) { bpe = maxBpe; } // max bytes per element for (n = 0; n < kv->maxNdx; n++) { binEncodeInt32(BUFFER_DATA(bf), bpe, keyDataBuf->i[n], isSigned); binAppendFmtField(bf, bpe, fmtCh); binAdvanceFmtBuffer(bf, bpe); } return BUFFER_DATA_LENGTH(bf); } else { // invalid data length (internal error) return PROP_ERROR_INVALID_LENGTH; } case KVT_BINARY: len = (BUFFER_DATA_SIZE(bf) < kv->lenNdx)? BUFFER_DATA_SIZE(bf) : kv->lenNdx; memcpy(BUFFER_DATA(bf), keyDataBuf->b, len); binAppendFmtField(bf, len, 'b'); binAdvanceFmtBuffer(bf, len); return PROP_ERROR(PROP_ERROR_OK, len); case KVT_STRING: // _propGetValue len = strLength((char*)keyDataBuf->b, keyDataSiz); if (len > BUFFER_DATA_SIZE(bf)) { len = BUFFER_DATA_SIZE(bf); } strncpy((char*)BUFFER_DATA(bf), (char*)keyDataBuf->b, len); if (len < BUFFER_DATA_SIZE(bf)) { BUFFER_DATA(bf)[len++] = 0; } // terminate if we have room binAppendFmtField(bf, len, 's'); binAdvanceFmtBuffer(bf, len); return PROP_ERROR(PROP_ERROR_OK, len); // length of string sans terminator case KVT_GPS: // _propGetValue (binary format) len = _propEncodeGPS(&(keyDataBuf->gps), bf); return PROP_ERROR(PROP_ERROR_OK, len); } } // unsupported type (internal error) return PROP_ERROR_INVALID_TYPE;} // _propGetValue/* get the specified property value as a byte array */// returns the number of bytes placed into the buffer// or -1, if there was an errorPropertyError_t propGetValue(Key_t key, UInt8 *data, int dataLen){ KeyValue_t *kv = propGetKeyValueEntry(key); if (!kv) { // invalid key return PROP_ERROR_INVALID_KEY; } else if (KVA_IS_WRITEONLY(kv->attr)) { // cannot read a write-only property return PROP_ERROR_WRITE_ONLY; } else if (KVT_TYPE(kv->type) == KVT_COMMAND) { // cannot read from a command // should not be here (all commands should be write-only) return PROP_ERROR_WRITE_ONLY; } else { PropertyError_t err; PROP_LOCK { _propRefresh(PROP_REFRESH_GET, kv, (UInt8*)0, 0); // args? FmtBuffer_t bb, *bf = binFmtBuffer(&bb, data, dataLen, 0, 0); err = _propGetValue(kv, bf); } PROP_UNLOCK return err; }}/* create a packet containing the specified property value (for sending to the server) */PropertyError_t propGetPropertyPacket(int protoNdx, Packet_t *pkt, Key_t key, UInt8 *args, int argLen){ KeyValue_t *kv = (KeyValue_t*)0;#if defined(SECONDARY_SERIAL_TRANSPORT) if ((key == PROP_STATE_DEVICE_ID) && (protoNdx == 1)) { kv = propGetKeyValueEntry(PROP_STATE_DEVICE_BT); } else { kv = propGetKeyValueEntry(key); }#else kv = propGetKeyValueEntry(key);#endif if (!kv) { // invalid key return PROP_ERROR_INVALID_KEY; } else if (KVA_IS_WRITEONLY(kv->attr)) { // cannot read a write-only property return PROP_ERROR_WRITE_ONLY; } else if (KVT_TYPE(kv->type) == KVT_COMMAND) { // cannot read from a command // should not be here (all commands should be write-only) return PROP_ERROR_WRITE_ONLY; } else { PropertyError_t err; PROP_LOCK { _propRefresh(PROP_REFRESH_GET, kv, args, argLen); // no args pktInit(pkt, PKT_CLIENT_PROPERTY_VALUE, (char*)0); // payload filled-in below FmtBuffer_t bb, *bf = pktFmtBuffer(&bb, pkt); binFmtPrintf(bf, "%2x", (UInt32)key); // property key err = _propGetValue(kv, bf); // property value pkt->dataLen = (UInt8)BUFFER_DATA_LENGTH(bf); // remember to save buffer length } PROP_UNLOCK return err; }}// ----------------------------------------------------------------------------// ----------------------------------------------------------------------------// ----------------------------------------------------------------------------// This section implements conversion of properties to/from ASCIIZ strings./* start-up initialization for individual KeyValue entry */static void _propInitKeyValueFromString(KeyValue_t *kv, const char *s, utBool internal){ /* reset attributes/length */ kv->lenNdx = 0; // reset actual length kv->dataSize = 0; if (internal) { kv->attr &= ~KVA_NONDEFAULT; // set to 'default' (clear non-default flag) } /* get key data buffer */ KeyData_t *keyDataBuf = _propGetData(kv); UInt16 keyDataSiz = _propGetDataCapacity(kv); memset(keyDataBuf, 0, keyDataSiz); // clear data buffer /* scan through types */ if (KVT_TYPE(kv->type) == KVT_COMMAND) { if (internal) { // reset/clear command type (value of string is ignored) keyDataBuf->cmd = 0; } return /*PROP_ERROR_OK*/; } /* parse for specific type */ int len = 0; if (!s) { s = ""; } // <-- 's' must not be null switch (KVT_TYPE(kv->type)) { case KVT_UINT8: case KVT_UINT16: case KVT_UINT24: case KVT_UINT32: while ((kv->lenNdx < kv->maxNdx) && (((kv->lenNdx + 1) * sizeof(UInt32)) <= keyDataSiz)) { UInt32 val = 0L; if (KVT_DEC(kv->type) > 0) { double dval = strParseDouble(s, 0.0); val = Double_to_UInt32(dval, kv->type); } else if (strStartsWithIgnoreCase(s,"0x")) { val = strParseHex32(s, 0x0000L); } else { val = strParseUInt32(s, 0L); } keyDataBuf->i[kv->lenNdx] = val; kv->lenNdx++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -