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 void Initialize(out ZigBeeDevice adapter) { // initialize communication with XBee module try { m_serialController.InitializeAsync().Wait(); } catch (Exception ex) { Debug.WriteLine("{0}.{1}: An exception occurred:\n {2}", this.GetType().Name, nameof(this.Initialize), ex); throw; } m_serialController.OnByteReception += GetBytesFromModule; // make sure there is a valid command Id NextCommandId(); // get information about XBee module //----------------------------------- // get hardware version HV_Command hvCommand = new HV_Command(); if (hvCommand.SendAndWaitResponse(this)) { m_HWVersion = hvCommand.HWVersion; } // get software version VR_Command vrCommand = new VR_Command(); if (vrCommand.SendAndWaitResponse(this)) { m_SWVersion = vrCommand.SWVersion; } // get MAC address byte[] macAddress = null; SL_Command slCommand = new SL_Command(); SH_Command shCommand = new SH_Command(); if (slCommand.SendAndWaitResponse(this) && shCommand.SendAndWaitResponse(this)) { macAddress = new byte[shCommand.MacAddressHightPart.Length + slCommand.MacAddressLowerPart.Length]; Array.Copy(shCommand.MacAddressHightPart, 0, macAddress, 0, shCommand.MacAddressHightPart.Length); Array.Copy(slCommand.MacAddressLowerPart, 0, macAddress, shCommand.MacAddressHightPart.Length, slCommand.MacAddressLowerPart.Length); } MY_Command myCommand = new MY_Command(); myCommand.SendAndWaitResponse(this); // set RX indicator mode // note this API mode is necessary to get response to ZDO and ZCL commands AO_Command aoCommand = new AO_Command(); aoCommand.SetRxIndicatorMode(this); adapter = new ZigBeeDevice(myCommand.NetworkAddress, AdapterHelper.UInt64FromXbeeFrame(macAddress, 0), false); }
public override bool ParseResponse(byte[] buffer) { if (m_commandList.Count == 0) { // no server command registered return(false); } // get Mac address, endpoint Id, cluster Id and command Id of source int offset = 0; UInt64 macAddress = AdapterHelper.UInt64FromXbeeFrame(buffer, offset); offset = AdapterHelper.MAC_ADDR_LENGTH; // skip network address (mac address is enough) offset += AdapterHelper.NETWORK_ADDRESS_LENGTH; byte endpointId = buffer[offset]; offset++; // skip destination end point offset++; UInt16 clusterId = AdapterHelper.UInt16FromXbeeFrame(buffer, offset); offset = GetZclCommandIdOffset(ref buffer); byte commandId = buffer[offset]; // find element that matches Mac address, network address, endpoint Id and cluster Id var element = Find(macAddress, endpointId, clusterId, commandId); if (element == null) { // no corresponding element for that Zcl server command return(false); } if (element.OnReception == null) { // no notification hence nothing else to do return(true); } // get parameters offset = GetZclPayloadOffset(ref buffer); // fill in out parameters foreach (var parameter in element.ParamList) { object value; if (!ZclHelper.GetValue(parameter.ZigBeeType, ref buffer, ref offset, out value)) { // can't get one of the out parameters => nothing else to do // note that return value is true because server command has been found but can't be parsed return(true); } parameter.Data = value; } // execute notification callback asynchronously Task.Run(() => { element.OnReception(element); }); return(true); }