public IEnumerable <ushort> Encode(SmartConfigContext ctx, SmartConfigArguments args) { // Data = total len(1 byte) + apPwd len(1 byte) + SSID CRC(1 byte) + // BSSID CRC(1 byte) + TOTAL XOR(1 byte)+ ipAddress(4 byte) + apPwd + apSsid apPwdLen <= // 105 at the moment var senderIPAddress = args.LocalAddress.GetAddressBytes(); var passwordBytes = args.Password != null?Encoding.ASCII.GetBytes(args.Password) : Constants.EmptyBuffer; var ssid = Encoding.UTF8.GetBytes(args.Ssid); var ssidCrc8 = Crc8.ComputeOnceOnly(ssid); var bssid = args.Bssid?.GetAddressBytes() ?? Constants.EmptyBuffer; var bssidCrc8 = Crc8.ComputeOnceOnly(bssid); var totalLength = (byte)(ExtraHeaderLength + senderIPAddress.Length + passwordBytes.Length + ssid.Length); byte totalXor = ComputeTotalXor(senderIPAddress, passwordBytes, ssid, ssidCrc8, bssidCrc8, totalLength); _framesBuilder.Clear(); this.DoEncode(totalLength, (byte)passwordBytes.Length, ssidCrc8, bssidCrc8, totalXor, senderIPAddress, passwordBytes, ssid, bssid); return(_framesBuilder); }
private async Task BroadcastSegmentForeverAsync( SmartConfigContext context, Segment segment, byte[] broadcastBuffer, CancellationToken token) { var segmentInterval = context.GetOption <TimeSpan>(StandardOptionNames.SegmentInterval); while (true) { await this.BroadcastSingleSegmentAsync(segment, broadcastBuffer, segmentInterval, token); } }
private async Task BroadcastSegmentByTimesAsync( SmartConfigContext context, Segment segment, byte[] broadcastBuffer, CancellationToken token) { var segmentInterval = context.GetOption <TimeSpan>(StandardOptionNames.FrameInterval); for (int i = 0; i < segment.BroadcastingMaxTimes; i++) { await this.BroadcastSingleSegmentAsync(segment, broadcastBuffer, segmentInterval, token); } }
private async Task BroadcastSegmentUntilAsync( SmartConfigContext context, Segment segment, byte[] broadcastBuffer, CancellationToken token) { var segmentInterval = context.GetOption <TimeSpan>(StandardOptionNames.SegmentInterval); var endTime = TimeSpan.FromMilliseconds(Environment.TickCount) + segment.BroadcastingPeriod; while ((TimeSpan.FromMilliseconds(Environment.TickCount) <= endTime) && !token.IsCancellationRequested) { await this.BroadcastSingleSegmentAsync(segment, broadcastBuffer, segmentInterval, token); } }
public IEnumerable <Segment> Encode(SmartConfigContext context, SmartConfigArguments args) { var guideTimeout = context.GetOption <TimeSpan>(StandardOptionNames.GuideCodeTimeout); var datumTimeout = context.GetOption <TimeSpan>(EspOptionNames.DatumPeriodTimeout); var frameInterval = context.GetOption <TimeSpan>(StandardOptionNames.FrameInterval); var datumEncoder = new EspDatumFrameEncoder(); var segFrames = new Segment[] { new Segment(EspWellKnownConstants.GuideCodes, frameInterval, guideTimeout), new Segment(datumEncoder.Encode(context, args), frameInterval, datumTimeout) }; return(segFrames); }
private async Task BroadcastProcedureAsync( SmartConfigContext context, IEnumerable <Segment> segments, byte[] broadcastBuffer, CancellationToken userCancelToken) { var segmentInterval = context.GetOption <TimeSpan>(StandardOptionNames.SegmentInterval); while (true) { userCancelToken.ThrowIfCancellationRequested(); foreach (var segment in segments) { userCancelToken.ThrowIfCancellationRequested(); if (segment.BroadcastingMaxTimes > 0) { await this.BroadcastSegmentByTimesAsync(context, segment, broadcastBuffer, userCancelToken); } else { var timerTask = Task.Delay(segment.BroadcastingPeriod, userCancelToken); using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(userCancelToken)) { linkedCts.CancelAfter(segment.BroadcastingPeriod); try { await this.BroadcastSegmentForeverAsync(context, segment, broadcastBuffer, linkedCts.Token); } catch (OperationCanceledException ocex) { if (userCancelToken.IsCancellationRequested) { throw ocex; } } } } await Task.Delay(segmentInterval, userCancelToken); } await Task.Delay(segmentInterval, userCancelToken); } }
private async Task ListenUntilCancelledAsync(SmartConfigContext context) { var interpreter = context.Provider.CreateDevicePacketInterpreter(); while (true) { var result = await _listeningSocket.ReceiveAsync(); if (result.Buffer != null && result.Buffer.Length > 0) { var remoteAddress = result.RemoteEndPoint.Address; if (interpreter.Validate(context, result.Buffer) && _reportedDeviceIPAddresses.TryAdd(remoteAddress, 0)) { var mac = interpreter.ParseMacAddress(result.Buffer); context.ReportDevice(new SmartConfigDevice(mac, remoteAddress)); } } } }
public IEnumerable <Segment> Encode(SmartConfigContext context, SmartConfigArguments args) { var frameInterval = context.GetOption <TimeSpan>(StandardOptionNames.FrameInterval); var builder = new List <Segment>(128); var ssid = Encoding.UTF8.GetBytes(args.Ssid); var ssidCrc8 = Crc8.ComputeOnceOnly(ssid); var password = args.Password != null?Encoding.UTF8.GetBytes(args.Password) : Constants.EmptyBuffer; // Guide Segment var guidePeriod = context.GetOption <TimeSpan>(StandardOptionNames.GuideCodeTimeout); builder.Add(new Segment(AirkissWellknownConstants.GuideCodes, frameInterval, guidePeriod)); // Magic Code Segment var magicCodeFrames = AirkissMagicCodeFrameEncoder.Encode(password.Length + ssid.Length + 1, ssidCrc8); var magicCodeTimeout = context.GetOption <TimeSpan>(AirkissOptionNames.MagicCodeTimeout); builder.Add(new Segment(magicCodeFrames, frameInterval, magicCodeTimeout)); // Prefix Code Segment var prefixCodeFrames = AirkissPrefixCodeFrameEncoder.Encode(password.Length); var prefixCodeTimeout = context.GetOption <TimeSpan>(AirkissOptionNames.PrefixCodeTimeout); builder.Add(new Segment(prefixCodeFrames, frameInterval, prefixCodeTimeout)); // Data(password/random/ssid) Segment var randValue = context.GetOption <byte>(AirkissOptionNames.RandomNumber); var buf = password.Append <byte>(randValue).Concat(ssid).ToList(); var dataFrames = new List <ushort>(buf.Count * 2); var index = 0; foreach (var bytes in buf.Partition(4)) { var seqEntryFrames = AirkissSeqEntryFrameEncoder.Encode(index, bytes); dataFrames.AddRange(seqEntryFrames); index++; } builder.Add(new Segment(dataFrames, frameInterval, TimeSpan.FromSeconds(4))); return(builder); }
public async Task ListenAsync( SmartConfigContext context, IPAddress localAddress, CancellationToken cancelToken) { if (_isStarted) { throw new InvalidOperationException("Already started."); } _isStarted = true; try { this.SetupSocket(context, localAddress); _reportedDeviceIPAddresses.Clear(); await this.ListenUntilCancelledAsync(context).WithCancellation(cancelToken); } finally { _isStarted = false; } }
public async Task BroadcastAsync(SmartConfigContext context, SmartConfigArguments args, CancellationToken cancelToken) { if (_isStarted) { throw new InvalidOperationException("Already started"); } try { _broadcastTarget = new IPEndPoint(IPAddress.Broadcast, context.GetOption <int>(StandardOptionNames.BroadcastingTargetPort)); var encoder = context.Provider.CreateProcedureEncoder(); var segments = encoder.Encode(context, args); var broadcastBuffer = this.CreateBroadcastBuffer(segments.SelectMany(x => x.Frames)); await this.BroadcastProcedureAsync(context, segments, broadcastBuffer, cancelToken); } finally { _isStarted = false; } }
private async Task BroadcastProcedureAsync( SmartConfigContext context, IEnumerable <Segment> segments, byte[] broadcastBuffer, CancellationToken userCancelToken) { var segmentInterval = context.GetOption <TimeSpan>(StandardOptionNames.SegmentInterval); while (true) { userCancelToken.ThrowIfCancellationRequested(); foreach (var segment in segments) { userCancelToken.ThrowIfCancellationRequested(); if (segment.BroadcastingMaxTimes > 0) { await this.BroadcastSegmentByTimesAsync(context, segment, broadcastBuffer, userCancelToken); } else { await this.BroadcastSegmentUntilAsync( context, segment, broadcastBuffer, userCancelToken); } if (segmentInterval > TimeSpan.Zero) { await Task.Delay(segmentInterval, userCancelToken); } } if (segmentInterval > TimeSpan.Zero) { await Task.Delay(segmentInterval, userCancelToken); } } }
public bool Validate(SmartConfigContext context, byte[] packet) { var randomValue = context.GetOption <byte>(AirkissOptionNames.RandomNumber); return(packet.Length == AirkissWellknownConstants.DevicePacketLength && packet[0] == randomValue); }
private void SetupSocket(SmartConfigContext context, IPAddress localAddress) { var listeningPort = context.GetOption <int>(StandardOptionNames.ListeningPort); _listeningSocket.Bind(new IPEndPoint(localAddress, listeningPort)); }
public bool Validate(SmartConfigContext context, byte[] packet) { return(packet.Length == EspWellKnownConstants.EspDevicePacketLength && packet[0] == EspWellKnownConstants.EspDevicePacketMagic); }