private void BeaconRequest()
        {
            bool send = true;
            Frame frame = null;

            lock (_state)
            {
                if (_state.autoBeacon)
                {
                    Header hdr = new Header();
                    hdr.fcs.SrcAddrMode = AddressingMode.Short;
                    hdr.srcAddrShort = _state.macShortAddr;
                    hdr.srcPanId = _state.macPanId;
                    hdr.seqNo = _state.macBSN++;

                    Beacon bc = new Beacon();
                    bc.beaconOrder = _state.macBeaconOrder;
                    bc.superframeOrder = _state.macSuperframeOrder;
                    // finalCapSlot
                    // batteryLifeExtension
                    if (_state.panCoordinator)
                        bc.panCoordinator = 1;
                    bc.associationPermit = 0;
                    // gtsPermit
                    // gtsDirectionsMask
                    // gtsDescriptor;
                    // shortAddrPending;
                    // extAddrPending;
                    bc.payload = _state.macBeaconPayload;

                    int lenHeader = hdr.Length();
                    int len = _state.phyFrameHead + lenHeader; ;
                    frame = Frame.GetFrame(len + bc.Length() + _state.phyFrameTail);
                    frame.ReserveHeader(len);
                    if (bc.WriteToFrame(frame) && hdr.WriteToFrameHeader(frame))
                    {
                        send = true;
                    }
                }
            }

            if (send)
            {
                _sendReceive.SendFrame(ref frame, false, 0);
            }

            Frame.Release(ref frame);
        }
Example #2
0
        private Frame Encode(Header header, Command.Base cmd)
        {
            int lenHeader = header.Length();
            int len = _state.phyFrameHead + lenHeader; ;
            Frame frame = Frame.GetFrame(len, cmd.LengthMax + _state.phyFrameTail);
            if (!cmd.WriteToFrame(frame) || !header.WriteToFrameHeader(frame))
            {
                Frame.Release(ref frame);
                Trace.Print("Mac: unable to create command frame");
                return null;
            }

            return frame;
        }
        private void DataRequest(TaskDataRequest task)
        {
            if (task == null)
                return;

            MacEnum result = MacEnum.Success;
            bool is2006 = false;
            // check frame
            if (task.msdu == null || task.msdu.LengthDataUsed == 0)
            {
                result = MacEnum.InvalidParameter;
            }
            else if (task.msdu.LengthDataUsed > State.aMaxMACSafePayloadSize)
            {
                if (_state.phySupports2006)
                {
                    is2006 = true;
                }
                else
                {
                    result = MacEnum.FrameTooLong;
                }
            }

            if (result == MacEnum.Success)
            {
                // data request is a value type, cannot be null
                Header hdr = new Header();

                hdr.fcs.Type = Frames.Type.Data;
                if (is2006)
                    hdr.fcs.Version = Frames.Version.IEEE2006;
                else
                    hdr.fcs.Version = Frames.Version.IEEE2003;
                if (task.options.AcknowledgedTransmission)
                    hdr.fcs.Ack = true;
                // FIXME: security

                lock (_state)
                {
                    hdr.seqNo = _state.macDSN++;

                    // dst address
                    hdr.dstPanId = task.dstPANId;
                    switch (task.dstAddr.Mode)
                    {
                        case MacAddressingMode.NoAddress:
                            hdr.fcs.DstAddrMode = AddressingMode.None;
                            break;
                        case MacAddressingMode.ShortAddress:
                            hdr.fcs.DstAddrMode = AddressingMode.Short;
                            hdr.dstAddrShort = task.dstAddr.ShortAddress;
                            break;
                        case MacAddressingMode.ExtendedAddress:
                            hdr.fcs.DstAddrMode = AddressingMode.Extended;
                            hdr.dstAddrExt = task.dstAddr.ExtendedAddress;
                            break;
                    }

                    // src addr
                    if (_state.macPanId == task.dstPANId)
                    {
                        hdr.fcs.PanIdCompression = true;
                    }
                    else
                    {
                        hdr.srcPanId = _state.macPanId;
                    }

                    switch (task.srcAddrMode)
                    {
                        case MacAddressingMode.NoAddress:
                            hdr.fcs.SrcAddrMode = AddressingMode.None;
                            break;
                        case MacAddressingMode.ShortAddress:
                            hdr.fcs.SrcAddrMode = AddressingMode.Short;
                            hdr.srcAddrShort = _state.macShortAddr;
                            break;
                        case MacAddressingMode.ExtendedAddress:
                            hdr.fcs.SrcAddrMode = AddressingMode.Extended;
                            hdr.srcAddrExt = _state.aExtendedAddress;
                            break;
                    }
                }

                // encode
                result = MacEnum.Congested;
                if (hdr.WriteToFrameHeader(task.msdu))
                {
                    if (task.msdu.LengthDataUsed > State.aMaxPhyPacketSize)
                    {
                        result = MacEnum.FrameTooLong;
                    }
                    else
                    {
                        result = _sendReceive.SendFrame(ref task.msdu, task.options.AcknowledgedTransmission, hdr.seqNo);
                    }
                }
                else
                {
                    Trace.Print("Mac: DataRequest: cannot add Mac header");
                }
            }

            Frame.Release(ref task.msdu);

            if (task.handler != null)
            {
                task.handler.Invoke(this, task.msduHandle, result);
            }
        }