public override bool ParseResponse(byte[] buffer) { if (!IsResponseOK(buffer)) { return(false); } // verify command Id int offset = GetZclCommandIdOffset(ref buffer); if (COMMAND_ID_DISCOVER_ATTRIBUTES_RESPONSE != buffer[offset]) { return(false); } // parse ZCL payload offset = GetZclPayloadOffset(ref buffer); // set discovery complete status m_discoveryCompleted = Convert.ToBoolean(buffer[offset]); offset++; while (offset < buffer.Length) { UInt16 id = AdapterHelper.UInt16FromZigBeeFrame(buffer, offset); m_attributeIdList.Add(id); offset += sizeof(UInt16); // skip type offset++; } return(true); }
public override bool ParseResponse(byte[] buffer) { UInt16 networkAddress; UInt64 macAddress; if (!IsResponseOK(buffer)) { return(false); } // verify network address matches with payload (requested network address) int offset = GetZdoPayloadOffset(); // skip 1st byte (ZDO command ref) offset++; // get network and Mac address networkAddress = AdapterHelper.UInt16FromZigBeeFrame(buffer, offset); offset += sizeof(UInt16); macAddress = AdapterHelper.UInt64FromZigBeeFrame(buffer, offset); // ignore capability (last byte) if (null != OnReception) { // execute notification callback asynchronously // can't determine is device is an end device from DeviceAnnce => assume it is one by default Task.Run(() => { OnReception(networkAddress, macAddress, true); }); } return(true); }
public override bool ParseResponse(byte[] buffer) { m_status = ZclHelper.ZCL_ERROR_FAILURE; if (!IsResponseOK(buffer)) { return(false); } // verify command Id int offset = GetZclCommandIdOffset(ref buffer); if (COMMAND_ID_READ_ATTRIBUTE_RESPONSE != buffer[offset]) { return(false); } // parse ZCL payload offset = GetZclPayloadOffset(ref buffer); // check attribute Id UInt16 id = AdapterHelper.UInt16FromZigBeeFrame(buffer, offset); if (id != m_Id) { return(false); } offset += sizeof(UInt16); // check status m_status = buffer[offset]; if (m_status != ZclHelper.ZCL_ERROR_SUCCESS) { return(false); } offset += ZIGBEE_STATUS_LENGTH; // set data bool retValue = false; object value = null; // from ZCL command payload // - 1st byte indicates the type // - following byte(s) contain the value byte type = buffer[offset]; offset += sizeof(byte); retValue = ZclHelper.GetValue(type, ref buffer, ref offset, out value); Value.Data = value; return(retValue); }
public override bool ParseResponse(byte[] buffer) { if (!IsResponseOK(buffer)) { return(false); } string bfString = ""; foreach (byte b in buffer) { bfString = bfString + Convert.ToString(b) + " "; } loggingServices.WriteLine <ManagementLQI>("GetNeighbors buffer = " + bfString); // get number of neighbor int offset = GetZdoPayloadOffset(); m_nbOfNeighbors = Convert.ToInt32(buffer[offset]); if (m_nbOfNeighbors == 0) { return(true); } // get start index and count in neighbor list offset++; int startIndex = Convert.ToInt32(buffer[offset]); int neighborCount = Convert.ToInt32(buffer[offset + 1]); /* 2017.11.03 - by 김진엽 * Xbee 모듈에서 보내온 버퍼에 m_nbOfNeighbors가 홀수인 경우 루프를 1회 더 수행하면서 디바이스 정보를 중복으로 가지고 오게 되는 현상 발견. * 안테나는 ManagementLQI 커맨드를 받으면 2개씩 끊어서 디바이스 정보를 보내오는것을 확인. * 이후의 로직을 수행하며 디바이스가 끊겨버리는 현상을 발생시킴. 수정 */ if (m_nbOfNeighbors % neighborCount > 0) { m_nbOfNeighbors--; } // get neighbors from table offset += 2; for (int index = 0; index < neighborCount; index++) { string strBuffer = ""; for (int i = 0; i < SIZEOF_NEIGHBOR_TABLE_ENTRY; i++) { strBuffer = strBuffer + Convert.ToString(buffer[offset + i]) + " "; } // get mac address and network address from neighbor table entry DeviceDescriptor descriptor = new DeviceDescriptor(); descriptor.networkAddress = AdapterHelper.UInt16FromZigBeeFrame(buffer, offset + NEIGHBOR_TABLE_ENTRY_NETWORK_ADDRESS_OFFSET); descriptor.macAddress = AdapterHelper.UInt64FromZigBeeFrame(buffer, offset + NEIGHBOR_TABLE_ENTRY_MAC_ADDRESS_OFFSET); byte deviceType = buffer[offset + NEIGHBOR_TABLE_ENTRY_DEVICE_TYPE_OFFSET]; descriptor.isEndDevice = ((deviceType & NEIGHBOR_TABLE_ENTRY_DEVICE_TYPE_MASK) == END_DEVICE_TYPE); // add device descriptor in device list m_neighborList.Add(descriptor); loggingServices.WriteLine <ManagementLQI>("[" + descriptor.macAddress + "] : " + strBuffer); // set offset of next entry offset += SIZEOF_NEIGHBOR_TABLE_ENTRY; } return(true); }
public override bool ParseResponse(byte[] buffer) { if (!IsResponseOK(buffer)) { return(false); } // verify network address matches with requested network address (1st part of payload) int offset = GetZdoPayloadOffset(); for (int index = 0; index < AdapterHelper.NETWORK_ADDRESS_LENGTH; index++) { if (m_payload[index] != buffer[offset + index]) { return(false); } } // get descriptor size offset += AdapterHelper.NETWORK_ADDRESS_LENGTH; int descriptorSize = Convert.ToInt32(buffer[offset]); if (descriptorSize < MIN_DESCRIPTOR_SIZE) { // "empty" or no descriptor => no info return(false); } // verify end point Id matches with requested end point Id (2nd part of payload) offset++; if (m_payload[AdapterHelper.NETWORK_ADDRESS_LENGTH] != buffer[offset]) { return(false); } // get profile Id and device Id offset++; m_profileId = AdapterHelper.UInt16FromZigBeeFrame(buffer, offset); offset += sizeof(UInt16); m_deviceId = AdapterHelper.UInt16FromZigBeeFrame(buffer, offset); offset += sizeof(UInt16); // skip next byte offset++; // get nb of in clusters (1 byte converted to int) int nbOfInClusters = Convert.ToInt32(buffer[offset]); // get id of in clusters offset++; for (int index = 0; index < nbOfInClusters; index++) { UInt16 tempVal = AdapterHelper.UInt16FromZigBeeFrame(buffer, offset); m_inClusterList.Add(tempVal); offset += sizeof(UInt16); } // get nb of out clusters (1 byte converted to int) int nbOfOutClusters = Convert.ToInt32(buffer[offset]); // get id of out clusters offset++; for (int index = 0; index < nbOfOutClusters; index++) { UInt16 tempVal = AdapterHelper.UInt16FromZigBeeFrame(buffer, offset); m_outClusterList.Add(tempVal); offset += sizeof(UInt16); } return(true); }
public override bool ParseResponse(byte[] buffer) { SOURCE_INFO sourceInfo = new SOURCE_INFO(); // verify command Id int offset = GetZclCommandIdOffset(ref buffer); if (COMMAND_ID_REPORT_ATTRIBUTES != buffer[offset]) { return(false); } if (OnReception == null) { // can't signal anything // however this is not an error => return true return(true); } // get Mac address, network address, endpoint Id and cluster Id of source offset = 0; sourceInfo.macAddress = AdapterHelper.UInt64FromXbeeFrame(buffer, offset); offset = AdapterHelper.MAC_ADDR_LENGTH; sourceInfo.networkAddress = AdapterHelper.UInt16FromXbeeFrame(buffer, offset); offset += AdapterHelper.NETWORK_ADDRESS_LENGTH; sourceInfo.endpointId = buffer[offset]; offset++; // skip destination end point offset++; sourceInfo.clusterId = AdapterHelper.UInt16FromXbeeFrame(buffer, offset); string strBuffer = ""; foreach (byte b in buffer) { strBuffer = strBuffer + b.ToString() + " "; } loggingServices.WriteLine <ZclReportAttributes>("strBuffer = [" + strBuffer + "]"); loggingServices.WriteLine <ZclReportAttributes>("macAddress = [" + sourceInfo.macAddress + "]"); loggingServices.WriteLine <ZclReportAttributes>("networkAddress = [" + sourceInfo.networkAddress + "]"); loggingServices.WriteLine <ZclReportAttributes>("endpointId = [" + sourceInfo.endpointId + "]"); loggingServices.WriteLine <ZclReportAttributes>("clusterId = [" + sourceInfo.clusterId + "]"); // parse ZCL payload offset = GetZclPayloadOffset(ref buffer); loggingServices.WriteLine <ZclReportAttributes>("offset of addributeId = [" + offset + "]"); while (offset < buffer.Length) { object value = null; // from ZCL report attribute payload // - 1st byte is the attribute Id // - 2nd byte indicates the type // - following byte(s) contain the value UInt16 attributeId = AdapterHelper.UInt16FromZigBeeFrame(buffer, offset); loggingServices.WriteLine <ZclReportAttributes>("attributeId = [" + attributeId + "]"); offset += sizeof(UInt16); byte type = buffer[offset]; offset += sizeof(byte); loggingServices.WriteLine <ZclReportAttributes>("offset of value = [" + offset + "]"); if (!ZclHelper.GetValue(type, ref buffer, ref offset, out value)) { // give up if attribute can't be retrieved break; } // execute notification callback asynchronously Task.Run(() => { OnReception(sourceInfo, attributeId, value); }); } return(true); }
public static bool GetValue(byte type, ref byte[] buffer, ref int offset, out object value) { value = null; switch (type) { case BOOLEAN_TYPE: { if (buffer.Length >= offset + sizeof(bool)) { bool tempVal = Convert.ToBoolean(buffer[offset]); value = tempVal; offset += sizeof(bool); } } break; case CHAR_STRING_TYPE: { if (buffer.Length >= offset + sizeof(byte)) { int length = Convert.ToInt32(buffer[offset]); if (length != 0 && buffer.Length >= (offset + (length + 1) * sizeof(byte))) { offset += sizeof(byte); String tempVal = Encoding.UTF8.GetString(buffer, offset, length); value = tempVal; offset += (length + 1) * sizeof(byte); } } } break; case INT8_TYPE: { if (buffer.Length >= offset + sizeof(sbyte)) { sbyte tempVal = (sbyte)buffer[offset]; value = tempVal; offset += sizeof(sbyte); } } break; case ENUMERATION_8_BIT_TYPE: // expected fall through case BITMAP_8_BIT_TYPE: // expected fall through case UINT8_TYPE: { if (buffer.Length >= offset + sizeof(byte)) { byte tempVal = buffer[offset]; value = tempVal; offset += sizeof(byte); } } break; case INT16_TYPE: { if (buffer.Length >= offset + sizeof(Int16)) { value = AdapterHelper.Int16FromZigBeeFrame(buffer, offset); offset += sizeof(Int16); } } break; case ENUMERATION_16_BIT_TYPE: // expected fall through case BITMAP_16_BIT_TYPE: // expected fall through case UINT16_TYPE: { if (buffer.Length >= offset + sizeof(UInt16)) { value = AdapterHelper.UInt16FromZigBeeFrame(buffer, offset); offset += sizeof(UInt16); } } break; case INT32_TYPE: { if (buffer.Length >= offset + sizeof(Int32)) { value = AdapterHelper.Int32FromZigBeeFrame(buffer, offset); offset += sizeof(Int32); } } break; case UINT32_TYPE: { if (buffer.Length >= offset + sizeof(UInt32)) { value = AdapterHelper.UInt32FromZigBeeFrame(buffer, offset); offset += sizeof(UInt32); } } break; case IEEE_ADDRESS_TYPE: { if (buffer.Length >= offset + sizeof(UInt64)) { value = AdapterHelper.UInt64FromZigBeeFrame(buffer, offset); offset += sizeof(UInt64); } } break; } if (value != null) { return(true); } else { return(false); } }