// Read parameter values from RAM or EEPROM. // Command syntax: data[]={ readId, cmdFlags, page, <numRead:>numToRead, {parameterIndexes}+ } // <[{[VarKind[,StoreFlgs,ArgsFlgs,value data]}*]>. // Or: data[]={ readId, cmdFlags, page, name} when BX_MEDIATOR_DEVICE_RWV_FLAGS_BY_NAME cmdFlag set. // In reply to a BY_NAME: strips out request name and sets NAME flag to reply in std form. // Returns number of values read / changed depending on readFlags: // BX_MEDIATOR_DEVICE_MONITORVAR = Iso compare and return true if parameters have changed. // For each parameter, replies with: // {DSK [,DSF, [ ramValue,] [ eepromValue,] [defaultValue] // [dataSize, minValue, maxValue] [name + '\0'] ]}. public byte MediatorReadCommand(MessageTransaction mtx) { DeviceParameterTable pt = Exchange.ParameterTable; DeviceParameter d; PacketBuffer g = mtx.MsgBuffer; byte[] pAry; int numReadIndex, dataIndex; bool addMeta, addKindOnly; byte n, j, k, byteCount, numToRead; byte readId, cmdFlags, pageNum, parameterVarKind, parameterFlags, parameterSize, metaSize; byte c = 0, maxData = (byte)(Exchange.Manager.MaxPacketSize - ProtocolConstants.GENERAL_OVERHEADS_SIZE); byte[] paramIndexes = new byte[8]; n = g.dataLength(); if (n < 5) { return(0); } numReadIndex = -1; dataIndex = ProtocolConstants.GENERAL_DATA_ARRAY_OFFSET; pAry = g.buffer; readId = pAry[dataIndex++]; cmdFlags = pAry[dataIndex++]; pageNum = pAry[dataIndex++]; n -= 3; // TODO: table page selection. addKindOnly = (cmdFlags & ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_PACK_KIND) != 0; addMeta = addKindOnly || (cmdFlags & ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_PACK) == 0; if ((cmdFlags & ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_BY_NAME) != 0) { pAry[dataIndex + n] = 0; string name = Primitives.GetArrayStringValue(pAry, dataIndex, n); // Search for name in table. d = pt.Find(name); if (d == null) { pAry[dataIndex - 1] = cmdFlags; dataIndex += n; numToRead = 0; } else { // If found, fall through and add meta data. cmdFlags |= ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_NAME; numToRead = 1; paramIndexes[0] = (byte)d.ParamIndex; } } else { --n; numToRead = (byte)(pAry[dataIndex++] & 0xf); if (numToRead > n) { numToRead = n; } j = numToRead; if (numToRead > 8) { numToRead = 8; } for (k = 0; k < numToRead; k++) { paramIndexes[k] = pAry[dataIndex + k]; } } if (numToRead > 0) { dataIndex = ProtocolConstants.GENERAL_DATA_ARRAY_OFFSET; pAry = g.buffer; pAry[dataIndex++] = readId; pAry[dataIndex++] = cmdFlags; // Restore parameters. pAry[dataIndex++] = pageNum; numReadIndex = dataIndex; pAry[dataIndex++] = 0; for (k = 0; k < numToRead; k++) { pAry[dataIndex++] = paramIndexes[k]; } } byteCount = (byte)dataIndex; g.dataLength(byteCount); k = 0; while (k < numToRead) { byte paramIndex = paramIndexes[k]; if (paramIndex > pt.GetLastEntryIndex()) { break; } d = pt.Find(paramIndex); if (d == null) { d = DeviceParameterTable.NullParameter; } n = 0; parameterVarKind = (byte)d.ParamVarKind; if (addMeta) { // Write out representation kind. metaSize = 1; if ((byteCount + metaSize) >= maxData) { break; } pAry[dataIndex + n++] = parameterVarKind; } else { metaSize = 0; } if (parameterVarKind != (byte)VariableKind.VK_None) { VariableValue p; byte[] b; byte argsFlags, argsIndex = 0; parameterSize = (byte)d.ParamSize; parameterFlags = (byte)d.ParamStorageFlags; if (addMeta && !addKindOnly) { // Write out parameter flags & space for argsFlags. metaSize += 2; if ((byteCount + metaSize) >= maxData) { break; } pAry[dataIndex + n++] = parameterFlags; argsIndex = n++; } argsFlags = 0; // Now write out parameter details depending on cmd flags. if (((cmdFlags & ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_RAM) != 0) && ((parameterFlags & (byte)StorageFlags.SF_RAM) != 0)) { p = d.RamValue; if (p != null) { if (parameterVarKind == (byte)VariableKind.VK_String) // Get size of string. { byte maxSize = (byte)d.MaxValue.ValueLong; int s = p.ValueString.Length; if (s > maxSize) { s = maxSize; } parameterSize = (byte)(1 + s); // Allow one for len byte. } if ((byteCount + metaSize + parameterSize) < maxData) { argsFlags |= ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_RAM; metaSize += parameterSize; if (parameterVarKind == (byte)VariableKind.VK_String) // Prefix a len byte. { --parameterSize; pAry[dataIndex + n++] = parameterSize; b = Primitives.StringToByteArray(p.ValueString); for (j = 0; j < parameterSize; j++) { pAry[dataIndex + n++] = b[j]; } } else { if ((mtx.TaskCmd != ProtocolConstants.MEDIATOR_DEVICE_ISOMONVAR) || (c != 0) || (paramIndex == ProtocolConstants.PARAMETER_TABLE_INDEX_TICKER)) { Array.Copy(p.GetBytes(), 0, pAry, dataIndex + n, parameterSize); } else { int h = parameterSize; b = p.GetBytes(); if (h > b.Length) { h = b.Length; } for (j = 0; j < parameterSize; j++) { int i = dataIndex + n + j; if ((c == 0) && pAry[i] != b[j]) { c = 1; } pAry[i] = b[j]; } } n += parameterSize; } } } } if (((cmdFlags & ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_EEPROM) != 0) && ((parameterFlags & (byte)StorageFlags.SF_EEPROM) != 0)) { p = d.EEPromValue; if (p != null) { if (parameterVarKind == (byte)VariableKind.VK_String) // Get size of string. { byte maxSize = (byte)d.MaxValue.ValueLong; int s = p.ValueString.Length; if (s > maxSize) { s = maxSize; } parameterSize = (byte)(1 + s); // Allow one for len byte. } if ((byteCount + metaSize + parameterSize) < maxData) { argsFlags |= ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_EEPROM; metaSize += parameterSize; if (parameterVarKind == (byte)VariableKind.VK_String) // Prefix a len byte. { --parameterSize; pAry[dataIndex + n++] = parameterSize; b = p.GetBytes(); for (j = 0; j < parameterSize; j++) { pAry[dataIndex + n++] = b[j]; } } else { Array.Copy(p.GetBytes(), 0, pAry, dataIndex + n, parameterSize); n += parameterSize; } } } } if (parameterVarKind == (byte)VariableKind.VK_String) { parameterSize = 1; } else { if ((cmdFlags & ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_DEFAULT) != 0) { if ((byteCount + metaSize + parameterSize) < maxData) { argsFlags |= ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_DEFAULT; metaSize += parameterSize; Array.Copy(d.DefaultValue.GetBytes(), 0, pAry, dataIndex + n, parameterSize); n += parameterSize; } } } if ((cmdFlags & ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_RANGE) != 0) { byte rangeSize = (byte)(2 + parameterSize * 2); if ((byteCount + metaSize + rangeSize) < maxData) { argsFlags |= ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_RANGE; metaSize += rangeSize; pAry[dataIndex + n++] = parameterSize; pAry[dataIndex + n++] = (byte)d.ParamCategory; Array.Copy(d.MinValue.GetBytes(), 0, pAry, dataIndex + n, parameterSize); n += parameterSize; Array.Copy(d.MaxValue.GetBytes(), 0, pAry, dataIndex + n, parameterSize); n += parameterSize; } } if ((cmdFlags & ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_NAME) != 0) { // Get size of string. parameterSize = 0; string s = d.ParamName; if (s != null) { parameterSize = (byte)s.Length; } if (parameterSize > ProtocolConstants.MAX_PARAMETER_NAME_SIZE) { parameterSize = ProtocolConstants.MAX_PARAMETER_NAME_SIZE; } if ((byteCount + metaSize + 1 + parameterSize) < maxData) { argsFlags |= ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_NAME; metaSize += (byte)(1 + parameterSize); pAry[dataIndex + n++] = parameterSize; b = Primitives.StringToByteArray(s); for (j = 0; j < parameterSize; j++) { pAry[dataIndex + n++] = b[j]; } } } if (addMeta && !addKindOnly) { pAry[dataIndex + argsIndex] = argsFlags; } } byteCount += metaSize; dataIndex += metaSize; g.dataLength((byte)(g.dataLength() + metaSize)); ++k; } if (numReadIndex >= 0) { g.buffer[numReadIndex] = (byte)((k << 4) + numToRead); } mtx.ChangeDir = true; mtx.Finish = MessageTransaction.FinishAction.Normal; if (mtx.TaskCmd == ProtocolConstants.MEDIATOR_DEVICE_ISOMONVAR) { return(c); } return(k); }
// Write parameter values to RAM or EEPROM. // Writes default value if no value given. // Command syntax: data[]={writeId, cmdFlags, page, <numWritten:>numToWrite, {parameterIndex}+[data]. // Returns number written along with parameter Index's. byte MediatorWriteCommand(MessageTransaction mtx) { DeviceParameterTable pt = Exchange.ParameterTable; DeviceParameter d; PacketBuffer g = mtx.MsgBuffer; byte[] pAry; int dataIndex; VariableValue val = null; byte n, h, k, j, writeId, cmdFlags, pageNum, retArgsLen, maxSize = 0; VariableKind parameterVarKind; StorageFlags parameterFlags; byte parameterSize, numToWrite; int paramIndexes, numWrittenIndex; n = g.dataLength(); if (n < 5) { return(0); } dataIndex = ProtocolConstants.GENERAL_DATA_ARRAY_OFFSET; pAry = g.buffer; writeId = pAry[dataIndex++]; cmdFlags = pAry[dataIndex++]; pageNum = pAry[dataIndex++]; numWrittenIndex = dataIndex; numToWrite = (byte)(pAry[dataIndex++] & 0xf); n -= 4; if (numToWrite > n) { numToWrite = n; } j = numToWrite; if (numToWrite > 8) { numToWrite = 8; } paramIndexes = dataIndex; retArgsLen = (byte)(dataIndex + numToWrite); g.dataLength((byte)(g.dataLength() - (4 + j))); //3=(wId, cmdFlags, page, nW:nTW), j= num original idx's. dataIndex += j; h = 0; k = 0; while (k < numToWrite) { int paramIndex = pAry[paramIndexes + k]; if (paramIndex > pt.GetLastEntryIndex()) { break; } d = pt.Find(paramIndex); if (d == null) { d = DeviceParameterTable.NullParameter; } parameterSize = (byte)d.ParamSize; if (parameterSize != 0) { int valPtrIndex = 0; parameterVarKind = (VariableKind)d.ParamVarKind; parameterFlags = (StorageFlags)d.ParamStorageFlags; if (parameterVarKind == VariableKind.VK_String) // Note: only one string allowed per message. { parameterSize = 0; if (n > 0) // Strings must be at least 1 byte long: len byte. { byte lenAdj; maxSize = (byte)d.MaxValue.ValueLong; parameterSize = pAry[dataIndex++]; lenAdj = parameterSize; n--; if (parameterSize > maxSize) { parameterSize = maxSize; } if (n < parameterSize) { parameterSize = n; lenAdj = parameterSize; } valPtrIndex = dataIndex; n -= lenAdj; dataIndex += lenAdj; } } else { if (n >= parameterSize) { val = new VariableValue(parameterVarKind, pAry, dataIndex, (int)parameterSize); valPtrIndex = dataIndex; n -= parameterSize; dataIndex += parameterSize; } else { val = d.DefaultValue; valPtrIndex = -1; } val.CheckInRange(d.MinValue, d.MaxValue); } if (parameterSize > 0) { if ((parameterFlags & StorageFlags.SF_ReadOnly) == 0) { if (((cmdFlags & ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_EEPROM) != 0) && ((parameterFlags & StorageFlags.SF_EEPROM) != 0)) { if (parameterVarKind == VariableKind.VK_String) { if (valPtrIndex >= 0) { d.EEPromValue = new VariableValue(parameterVarKind, pAry, valPtrIndex, (int)parameterSize); } else { d.EEPromValue = new VariableValue(parameterVarKind, pAry, 0, (int)0); } } else { d.EEPromValue = val; } } if ((cmdFlags & ProtocolConstants.MEDIATOR_DEVICE_RWV_FLAGS_RAM) != 0) { if (parameterVarKind == VariableKind.VK_String) { if (valPtrIndex >= 0) { d.RamValue = new VariableValue(parameterVarKind, pAry, valPtrIndex, (int)parameterSize); } else { d.RamValue = new VariableValue(parameterVarKind, pAry, 0, (int)0); } } else { d.RamValue = val; } } } } ++h; } ++k; ++paramIndex; } if (numWrittenIndex >= 0) { pAry[numWrittenIndex] = h; // Reply to caller with number of parameters written. } g.dataLength(retArgsLen); mtx.ChangeDir = true; mtx.Finish = ((g.flagsRS() & ProtocolConstants.MESSAGE_FLAGS_ACK) != 0) ? MessageTransaction.FinishAction.Normal : MessageTransaction.FinishAction.Free; return(h); }