public override void on_data() { // agregarmos al buffer. //Marshall.Debug(string.Format("tcp reactor, datos en buffer={0} recibidos={1}", buffer_position, get_read_bytes())); Array.Copy(get_buffer(), 0, active_buffer, buffer_position, get_read_bytes()); buffer_position += get_read_bytes(); while (buffer_position > 5) { reset_position = 0; // tengo el tamaño del pdu y options. var size = UrbetrackCodec.DecodeShort(active_buffer, ref reset_position); //byte options = UnetelCodec.DecodeByte(active_buffer, ref reset_position); //Marshall.Debug(string.Format("tcp reactor, datos en buffer={0} recibidos={1} size={2}", buffer_position, get_read_bytes(), size)); // valido si esta completo en el buffer. if ((size + 2) < (buffer_position)) { return; // faltan datos } var pdu_buffer = new byte[size + 2]; // copiamos la pdu. Array.Copy(pdu_buffer, 0, active_buffer, 0, size + 2); try { var ret = Codes.DecodeErrors.NoError; var instance_buffer = new byte[get_read_bytes()]; Array.Copy(get_buffer(), instance_buffer, get_read_bytes()); if (_data.udp_fwd != null) { if (_data.udp_fwd_host != null) { STrace.Debug(GetType().FullName, string.Format("**** UDP FORWARD TO: {0}", _data.udp_fwd_host)); _data.udp_fwd.Send(instance_buffer, get_read_bytes(), _data.udp_fwd_host); } } var pdu = _data.CODEC.Decode(instance_buffer, ref ret); pdu.Transporte = _data; pdu.Destino = new Destino { TCP = ep }; var d = Devices.I().FindById(pdu.IdDispositivo); if (d != null) { d.Touch(pdu.Destino); } else { if ((Codes.HighCommand)pdu.CH != Codes.HighCommand.LoginRequest) { close(); return; } } var t = _data.ObtenerTransaccion(pdu.IdTransaccion); if (t == null) { if (pdu.CH < 0x80) { var mrs = new MRS(pdu, _data, _data.TransactionUser); _data.NuevaTransaccion(mrs, pdu); mrs.Start(); } } else { t.RecibePDU(pdu); } } catch (IndexOutOfRangeException e) { STrace.Exception(GetType().FullName, e); throw; } catch (Exception e) { STrace.Exception(GetType().FullName, e); } // Rotamos el Array Array.Copy(active_buffer, 0, active_buffer, size + 2, (buffer_position - (size + 2))); buffer_position -= size + 2; } }
private void _ReadCallback(IAsyncResult ar) { var myData = Thread.GetNamedDataSlot("device"); try { _read_bytes = _socket.EndReceiveFrom(ar, ref _remote_address); if (Hacker.UDP.DisableSocketRead) { STrace.Debug(GetType().FullName, String.Format("udp reactor, hackeado, tamaño={0}", _read_bytes)); _socket.BeginReceiveFrom(_read_buffer, 0, _buffersize, 0, ref _remote_address, _ReadCallback, _socket); Thread.SetData(myData, null); return; } try { var ret = Codes.DecodeErrors.NoError; var instance_buffer = new byte[get_read_bytes()]; Array.Copy(get_buffer(), instance_buffer, get_read_bytes()); PDU pdu = null; try { pdu = CODEC.Decode(instance_buffer, ref ret); } catch (Exception) { STrace.Debug(GetType().FullName, "PDU malformada!"); } if (pdu == null || ret != Codes.DecodeErrors.NoError) { STrace.Debug(GetType().FullName, String.Format("Error la PDU no se pudo decodificar reason={0}", ret)); Thread.SetData(myData, null); _socket.BeginReceiveFrom(_read_buffer, 0, _buffersize, 0, ref _remote_address, _ReadCallback, _socket); return; } pdu.Transporte = this; pdu.Destino = new Destino { UDP = (_remote_address as IPEndPoint) }; var d = Devices.I().FindById(pdu.IdDispositivo); Thread.SetData(myData, d); if (d != null && CODEC.AllowOfflineMessages) { d.Transporte = this; d.Touch(pdu.Destino); } else if (d != null && d.State == DeviceTypes.States.ONLINE) { STrace.Debug(GetType().FullName, String.Format("DEVICE[{0}]: TOUCH por mensaje CH={1}", d.LogId, pdu.CH)); d.Transporte = this; d.Touch(pdu.Destino); } else if (d != null) { if ((pdu.CH < 0x80) && ((Codes.HighCommand)pdu.CH) != Codes.HighCommand.LoginRequest) { if (CODEC.DontReplayWhenOffline) { // ignoramos todos los mensajes excepto LRQ cuando esta offline. STrace.Debug(GetType().FullName, String.Format("DEVICE[{0}]: Ignorando mensaje CH={1} por estar offline.", d.LogId, pdu.CH)); Thread.SetData(myData, null); _socket.BeginReceiveFrom(_read_buffer, 0, _buffersize, 0, ref _remote_address, _ReadCallback, _socket); return; } if (CODEC.SupportsLoginRequired) { // si el dispositivo no esta registrado, entonces enviamos // mensaje de registracion requerida. STrace.Debug(GetType().FullName, String.Format("DEVICE[{0}]: Enviando Login Requerido.", d.LogId)); var rta = new PDU { IdDispositivo = pdu.IdDispositivo, Seq = pdu.Seq, Options = pdu.Options, Destino = pdu.Destino, CH = ((byte)Codes.HighCommand.LoginRequerido), CL = 0x00 }; Send(rta); } Thread.SetData(myData, null); _socket.BeginReceiveFrom(_read_buffer, 0, _buffersize, 0, ref _remote_address, _ReadCallback, _socket); return; } } var devlog = (d != null ? d.LogId : "?"); var t = ObtenerTransaccion(pdu.IdTransaccion); if (t == null) { if (pdu.CH < 0x80) { var mrs = new MRS(pdu, this, TransactionUser); NuevaTransaccion(mrs, pdu); mrs.Start(); } else { STrace.Debug(GetType().FullName, String.Format("DEVICE[{0}]: RTA HUERFANA CH={1}", devlog, pdu.CH)); } } else { STrace.Debug(GetType().FullName, String.Format("DEVICE[{0}]: Recivo Retransmision CH={1}", devlog, pdu.CH)); t.RecibePDU(pdu); } } catch (ObjectDisposedException e) { STrace.Debug(GetType().FullName, e.Message); } catch (Exception e) { STrace.Exception(GetType().FullName, e); } Thread.SetData(myData, null); _socket.BeginReceiveFrom(_read_buffer, 0, _buffersize, 0, ref _remote_address, _ReadCallback, _socket); } catch (Exception e) { if (e.Message != "An existing connection was forcibly closed by the remote host") { if (e is ObjectDisposedException) { STrace.Debug(GetType().FullName, e.Message); } else { STrace.Exception(GetType().FullName, e); } } Thread.SetData(myData, null); _socket.BeginReceiveFrom(_read_buffer, 0, _buffersize, 0, ref _remote_address, _ReadCallback, _socket); } }
private void _ReadCallback(IAsyncResult ar) { try { _read_bytes = _socket.EndReceiveFrom(ar, ref _remote_address); if (HACK_DisableSocketRead) { T.INFO(string.Format("udp reactor, hackeado, tamaño={0}", _read_bytes)); _socket.BeginReceiveFrom(_read_buffer, 0, _buffersize, 0, ref _remote_address, _ReadCallback, _socket); return; } T.TRACE(string.Format("UDP: reactor, recibio datagrama de size={0}", _read_bytes)); try { T.TRACE("---RECEIVING---------------------------------------------------------------"); var ret = Decoder.DecodeErrors.NoError; var instance_buffer = new byte[get_read_bytes()]; Array.Copy(get_buffer(), instance_buffer, get_read_bytes()); var pdu = Decoder.Decode(instance_buffer, ref ret); pdu.Transport = this; pdu.Destination = new Destination(); pdu.Destination.UDP = _remote_address as IPEndPoint; T.TRACE(pdu.Trace("")); Transaction t; t = ObtenerTransaccion(pdu.TransactionId); T.TRACE("UDP: trid=" + pdu.TransactionId); if (t == null) { TransactionUser ut = null; // Options 0 = mensaje de dispositivo. if (pdu.Options == 0x00) { T.TRACE("UDP: transaccion de usuario. "); ut = TransactionUser; } // Options 1 = mensaje de control de red. else if (pdu.Options == 0x01) { T.TRACE("UDP: transaccion para modulo de managment ch=" + pdu.CH); ut = Managment; } if (ut != null && pdu.CH < 0x80) { T.TRACE("UDP: transaccion nueva ch=" + pdu.CH); var mrs = new MRS(pdu, this, ut); NuevaTransaccion(mrs, pdu); mrs.Start(); } else { T.TRACE("UDP: pdu huerfana seq=" + pdu.Seq + " CH=" + pdu.CH + " CL=" + pdu.CL); } } else { T.TRACE("UDP: transaccion existente recibe PDU"); t.ReceivedPDU(pdu); } } catch (Exception e) { T.TRACE( string.Format("UDP: exception procesando PDU, local_address={1} remote address={0} texto={2}", _remote_address, _local_address, e)); } finally { T.TRACE("---------------------------------------------------------------------------"); _socket.BeginReceiveFrom(_read_buffer, 0, _buffersize, 0, ref _remote_address, _ReadCallback, _socket); } } catch (ObjectDisposedException) { // se ignora como excepcion, ya que se dispara por invocar Close del socket. T.TRACE(string.Format("excepcion, se asume que el reactor de udp esta detenido, address={0}", _local_address)); } catch (SocketException) { // se ignora por problemas de red. } }
public void Receive(byte[] source_buffer, int size, XBeeAddress addr) { try { var ret = Codes.DecodeErrors.NoError; var instance_buffer = new byte[size]; Array.Copy(source_buffer, instance_buffer, size); var pdu = CODEC.Decode(instance_buffer, ref ret); if (pdu == null || ret != Codes.DecodeErrors.NoError) { STrace.Debug(GetType().FullName, String.Format("XBEE: Error la PDU no se pudo decodificar reason={0}", ret)); return; } pdu.Transporte = this; pdu.Destino = new Destino { XBee = addr }; var d = Devices.I().FindById(pdu.IdDispositivo); var devlog = (d != null ? d.LogId : "?"); var myData = Thread.GetNamedDataSlot("device"); Thread.SetData(myData, d); STrace.Debug(GetType().FullName, pdu.Trace("")); if (d != null) { d.Trace(); } if (d != null && d.State == DeviceTypes.States.ONNET) { d.Transporte = this; d.Touch(pdu.Destino); } else if (d != null) { if ((Codes.HighCommand)pdu.CH != Codes.HighCommand.LoginRequest) { // si el dispositivo no esta registrado, entonces enviamos // mensaje de registracion requerida. STrace.Debug(GetType().FullName, String.Format("DEVICE[{0}]/XBEE: Enviando Login requerido", devlog)); var rta = new PDU { IdDispositivo = pdu.IdDispositivo, Seq = pdu.Seq, Options = pdu.Options, Destino = pdu.Destino, CH = ((byte)Codes.HighCommand.LoginRequerido), CL = 0x00 }; Send(rta); Thread.SetData(myData, null); return; } } var t = ObtenerTransaccion(pdu.IdTransaccion); if (t == null) { if (pdu.CH < 0x80) { STrace.Debug(GetType().FullName, String.Format("DEVICE[{0}]/XBEE: Nueva Transaccion Entrante CH={1} Seq={2}", devlog, pdu.CH, pdu.Seq)); var mrs = new MRS(pdu, this, TransactionUser); if (d != null && d.HackBugXBEEv99) { d.Transporte = this; } NuevaTransaccion(mrs, pdu); mrs.Start(); } else { STrace.Debug(GetType().FullName, String.Format("DEVICE[{0}]/XBEE: RTA HUERFANA CH={1}", devlog, pdu.CH)); } } else { STrace.Debug(GetType().FullName, String.Format("DEVICE[{0}]/XBEE: Recivo Retransmision CH={1} Seq={2}", devlog, pdu.CH, pdu.Seq)); t.RecibePDU(pdu); } } catch (Exception e) { STrace.Exception(GetType().FullName, e); } }