private Results ProcessPacket(byte[] bytes, bool isOutbound, DateTime timestamp) { if (mTerminated) { return(Results.Terminated); } if (Build == 0) { var packet = new ByteReader(bytes); packet.Read <ushort>(); // rawSeq int length = packet.ReadInt(); if (bytes.Length - 6 < length) { logger.Debug($"Connection on port {mLocalEndpoint} did not have a MapleStory2 Handshake"); return(Results.CloseMe); } ushort opcode = packet.Read <ushort>(); if (opcode != 0x01) { // RequestVersion logger.Debug($"Connection on port {mLocalEndpoint} did not have a valid MapleStory2 Connection Header"); return(Results.CloseMe); } uint version = packet.Read <uint>(); uint siv = packet.Read <uint>(); uint riv = packet.Read <uint>(); uint blockIV = packet.Read <uint>(); byte type = packet.ReadByte(); Build = version; Locale = MapleLocale.UNKNOWN; outDecryptor = new MapleCipher.Decryptor(Build, siv, blockIV); inDecryptor = new MapleCipher.Decryptor(Build, riv, blockIV); inDecryptor.Decrypt(bytes); // Advance the IV // Generate HandShake packet Definition definition = Config.Instance.GetDefinition(Build, Locale, false, opcode); if (definition == null) { definition = new Definition { Outbound = false, Opcode = opcode, Name = "RequestVersion", }; SaveDefinition(Locale, Build, definition); } ArraySegment <byte> segment = new ArraySegment <byte>(packet.Buffer); var maplePacket = new MaplePacket(timestamp, isOutbound, Build, opcode, segment); // Add to list of not exist (TODO: SortedSet?) if (!Opcodes.Exists(op => op.Outbound == maplePacket.Outbound && op.Header == maplePacket.Opcode)) { // Should be false, but w/e Opcodes.Add(new Opcode(maplePacket.Outbound, maplePacket.Opcode)); } AddPacket(maplePacket, false, true); logger.Info($"[CONNECTION] {mRemoteEndpoint} <-> {mLocalEndpoint}: MapleStory2 V{Build}"); return(Results.Show); } try { MapleCipher.Decryptor decryptor = isOutbound ? outDecryptor : inDecryptor; ByteReader packet = decryptor.Decrypt(bytes); // It's possible to get an empty packet, just ignore it. // Decryption is still necessary to advance sequence number. if (packet.Available == 0) { return(Results.Continue); } ushort opcode = packet.Peek <ushort>(); ArraySegment <byte> segment = new ArraySegment <byte>(packet.Buffer, 2, packet.Length - 2); var maplePacket = new MaplePacket(timestamp, isOutbound, Build, opcode, segment); AddPacket(maplePacket); return(Results.Continue); } catch (ArgumentException ex) { logger.Fatal(ex, "Exception while processing packets"); return(Results.CloseMe); } }
private void CheckFrame(short length, ByteReader br) { XBeeApiType apiId = (XBeeApiType)br.Peek(); XBeeResponse res = null; switch (apiId) { case XBeeApiType.ZNetExplicitRxIndicator: res = new ExplicitZigBeeResponse(length, br); break; case XBeeApiType.AtCommandResponse: res = new AtCommandResponse(length, br); break; case XBeeApiType.RemoteAtCommandResponse: res = new RemoteAtResponse(length, br); break; case XBeeApiType.ModemStatus: res = new ModemStatusResponse(length, br); if (res != null) { OnModemStatusChanged((res as ModemStatusResponse).ModemStatus); } break; case XBeeApiType.RxPacket16: res = new RxResponse16(length, br); break; case XBeeApiType.RxPacket64: res = new RxResponse64(length, br); break; case XBeeApiType.TxStatus: res = new TxStatusResponse(length, br); break; case XBeeApiType.NodeIdentificationIndicator: res = new ZNetNodeIdentificationResponse(length, br); break; case XBeeApiType.ZNetRxPacket: res = new ZNetRxResponse(length, br); break; case XBeeApiType.XBeeSensorReadIndicator: res = new XBeeSensorRead(length, br); break; case XBeeApiType.ZNetIODataSampleRxIndicator: res = new ZNetRxIoSampleResponse(length, br); break; case XBeeApiType.ZNetTxStatus: res = new ZNetTxStatusResponse(length, br); break; default: break; } if (res != null) { if (_waitResponse && res is XBeeResponse) { if (res is AtCommandResponse && (res as AtCommandResponse).FrameID != _frameID) { return; } _receivedPacket = res; _waitResponse = false; } else { OnFrameReceived(res); } } }
void CheckFrame() { if (_readBuffer.Count < 4) // we don't have the start byte, the length and the checksum { return; } if (_readBuffer[0] != XBeePacket.PACKET_STARTBYTE) { return; } ByteReader br = new ByteReader(_readBuffer.ToArray(), ByteOrder.BigEndian); br.ReadByte(); // start byte short length = br.ReadInt16(); if (br.AvailableBytes < length + 1) // the frame data and checksum { return; } // verify checksum XBeeChecksum checksum = new XBeeChecksum(); byte[] bytes = new byte[length + 1]; Array.Copy(_readBuffer.ToArray(), 3, bytes, 0, length + 1); checksum.AddBytes(bytes); Console.WriteLine(checksum.Verify()); XBeeApiType apiId = (XBeeApiType)br.Peek(); XBeeResponse res = null; Console.WriteLine("ApiID = " + apiId.ToString()); Console.WriteLine("length = " + length); switch (apiId) { case XBeeApiType.ATCommandResponse: res = new AtCommandResponse(length, br); break; case XBeeApiType.NodeIdentificationIndicator: res = new NodeIdentification(length, br); break; case XBeeApiType.ZigBeeReceivePacket: res = new ZigbeeReceivePacket(length, br); break; case XBeeApiType.XBeeSensorReadIndicator: res = new XBeeSensorRead(length, br); break; case XBeeApiType.RemoteCommandResponse: res = new AtRemoteCommandResponse(length, br); break; case XBeeApiType.ZigBeeIODataSampleRxIndicator: res = new ZigBeeIODataSample(length, br); break; default: Console.WriteLine("This API frame is unknown."); break; } if (res != null) { Console.WriteLine(res); } _readBuffer.RemoveRange(0, length + 1 + 2 + 1); Console.WriteLine("waiting " + _readBuffer.Count + " bytes"); }
private void CheckFrame() { if (_readBuffer.Count < 4) // we don't have the start byte, the length and the checksum { return; } if (_readBuffer[0] != XBeePacket.PACKET_STARTBYTE) { return; } ByteReader br = new ByteReader(_readBuffer.ToArray(), ByteOrder.BigEndian); br.ReadByte(); // start byte short length = br.ReadInt16(); if (br.AvailableBytes < length + 1) // the frame data and checksum { return; } // verify checksum XBeeChecksum checksum = new XBeeChecksum(); byte[] bytes = new byte[length + 1]; Array.Copy(_readBuffer.ToArray(), 3, bytes, 0, length + 1); checksum.AddBytes(bytes); if (!checksum.Verify()) { //TODO: ERRO no quadro. Limpar os recursos e retornar função return; } XBeeApiType apiId = (XBeeApiType)br.Peek(); XBeeResponse res = null; //TODO: implementar a descoberta de dispositivos switch (apiId) { case XBeeApiType.ATCommandResponse: res = new AtCommandResponse(length, br); if (res.Command == "ND") { byte[] dados = res.Value; } break; case XBeeApiType.NodeIdentificationIndicator: res = new NodeIdentification(length, br); break; case XBeeApiType.ZigBeeReceivePacket: res = new ZigbeeReceivePacket(length, br); break; case XBeeApiType.XBeeSensorReadIndicator: res = new XBeeSensorRead(length, br); break; case XBeeApiType.RemoteCommandResponse: res = new AtRemoteCommandResponse(length, br); if (res.Command == "IS") { XBee.XBee newDev; if (devices.TryGetValue(res.Address64, out newDev)) { devices[res.Address64].SetIOStatus(res.Value); } else { newDev = new XBee.XBee(res.Address64, res.Address16); devices.Add(res.Address64, newDev); devices[res.Address64].SetIOStatus(res.Value); //repetido } } break; case XBeeApiType.ZigBeeIODataSampleRxIndicator: res = new ZigBeeIODataSample(length, br); break; case XBeeApiType.APIIOSupportReceivePacket64bits: res = new APIIOSupportReceivePacket64bits(length, br); devices[res.Address64].SetIOStatus(res.Value); break; default: //TODO: tratar erro na leitura do pacote break; } if (res != null) { objAtual = res.ToString(); DataReceived(res.ToString()); } _readBuffer.RemoveRange(0, length + 1 + 2 + 1); }