private void OnModemResponse(bool ok) { if (CurrentModemState == ModemState.SendingSMS) { ProcessSmsResult(ok); } if (!ok) { NihLog.Write(NihLog.Level.Error, "Error during state " + CurrentModemState.ToString()); CurrentModemState = ModemState.Error; return; } switch (CurrentModemState) { case ModemState.NotInitialized: return; case ModemState.PowerUp: WriteToModem("ATE0;+CMGF=1;+CSCS=\"IRA\";+CNMI=1,2\r"); CurrentModemState = ModemState.Initializing; break; case ModemState.Initializing: case ModemState.SendingSMS: case ModemState.KeepAliveAwaitingResponse: CurrentModemState = ModemState.Idle; break; } }
private bool IsTransitionalState(ModemState ms) { return(ms == ModemState.Initializing || ms == ModemState.SendingSMS || ms == ModemState.PowerUp || ms == ModemState.KeepAliveAwaitingResponse); }
private void sendNextPacket() { int hcIndex = -1; int prio = -1; //Debug.Print("--> Send State" + State + " <--"); if (State == ModemState.Ready) { for (int i = 0; i < ChannelList.Length; i++) { if (ChannelList[i] != null) { if (ChannelList[i].BytesToSend > 0 && ChannelList[i].Priority > prio) { hcIndex = i; prio = ChannelList[i].Priority; } } } int byteCount; byte[] Buffer = new byte[64]; Buffer[0] = (byte)rxPackNr; Buffer[1] = (byte)txPackNr; Buffer[2] = (byte)hcIndex; Buffer[3] = CancelPacketFlag ? (byte)PacketAttrib.ClearRecvBuffer : (byte)PacketAttrib.Normal; //Debug.Print("--> Send hcIndex" + hcIndex + " <--"); if (hcIndex > -1) { byteCount = ChannelList[hcIndex].GetBytesFromTxBuffer(Buffer, 4, lastTxPackLen); //Debug.Print("** Send " + byteCount + " **"); State = ModemState.Transmitting; rf22_sendpacket(Buffer, 0, byteCount + 4); lastTxChan = ChannelList[hcIndex]; lastTxPackLen = byteCount; } else if (lastRxPackLen > 4) { //Debug.Print("** Send Empty **"); lastRxPackLen = 0; State = ModemState.Transmitting; rf22_sendpacket(Buffer, 0, 4); } else { rf22_rxmode(); } } }
void UninitModem() { if (modemPort != null) { modemPort.Dispose(); } modemPort = null; CurrentModemState = ModemState.NotInitialized; }
private void RecvTimeOut(object nullObj) { if (State == ModemState.Receving) { State = ModemState.Ready; RSSI = -1; if (LostPackets == int.MaxValue) { LostPackets = 0; } LostPackets++; sendNextPacket(); } }
public RFM22b(SPI.SPI_module SpiMmodule, Cpu.Pin ChipSelectPort, Cpu.Pin IRQPort, double FrequInHz) { SpiConfig = new SPI.Configuration(ChipSelectPort, false, 0, 0, false, true, 1000, SpiMmodule); SpiBus = new SPI(SpiConfig); IRQn = new InterruptPort(IRQPort, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow); IRQn.OnInterrupt += new NativeEventHandler(IRQn_OnInterrupt); rf22_init(); rf22_setfreq((byte)((_frequency - 860.0) * 3200)); rf22_rxmode(); TimeOutTimer = new Timer(new TimerCallback(RecvTimeOut), null, 500, Timeout.Infinite); State = ModemState.Receving; }
void TryInitModem() { // Try pistoning the modem with higher frequency. This does no harm (such as redundant logging) PrepareU9Modem(); // Will do nothing if modem is okay if (!_initFailureTimeout.IsTimedOut()) { return; // Don't try too frequently } if (modemPort != null) { return; } const string modemPortName = "Basecom HS-USB NMEA 9000"; const int speed = 115200; string portName = Hardware.Misc.SerialPortFromFriendlyName(modemPortName); if (portName == null) { NihLog.Write(NihLog.Level.Error, "Modem not found (yet). "); _initFailureTimeout.Reset(); return; } NihLog.Write(NihLog.Level.Info, string.Format("Found modem port \"{0}\" at {1}", modemPortName, portName)); modemPort = new System.IO.Ports.SerialPort(portName, speed); modemPort.ReadTimeout = 3000; modemPort.NewLine = "\r\n"; modemPort.Open(); modemPort.DiscardInBuffer(); modemPort.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(delegate { _mainThreadOwnder.Invoke(dataReceivedDelegate); }); // called in different thread! _lastModemKeepAlive = new Timeouter(60, true); WriteToModem("AT+CFUN=1\r"); CurrentModemState = ModemState.PowerUp; }
private void IRQn_OnInterrupt(uint port, uint state, DateTime time) { InterruptStatus1 = rf22_read(0x03); if (State == ModemState.Transmitting) { // All Data Transmitted rf22_write(0x07, 0x01); // switch to ready mode rf22_rxmode(); TimeOutTimer.Dispose(); TimeOutTimer = new Timer(new TimerCallback(RecvTimeOut), null, 500, Timeout.Infinite); State = ModemState.Receving; } else if (State == ModemState.Receving || State == ModemState.Ready) { RSSI = rf22_read(0x26); State = ModemState.Ready; readPacket(); sendNextPacket(); } }
private void SendSmsNow() { OutboundSMS sms = _outSmses.Peek(); sms.Attempt++; if (sms.Attempt > sms.MaxTries) { NihLog.Write(NihLog.Level.Error, "Failure to send after " + sms.MaxTries + " tries"); _outSmses.Dequeue(); return; } NihLog.Write(NihLog.Level.Info, "Sending SMS: " + sms.ToString()); WriteToModem("AT+CMGS=\"" + sms.Destination + "\"\r"); System.Threading.Thread.Sleep(500); WriteToModem(sms.Text); byte[] buffer = new byte[1]; buffer[0] = 26; // ^Z modemPort.Write(buffer, offset: 0, count: 1); CurrentModemState = ModemState.SendingSMS; }
public void HeartBeat() { if (CurrentModemState == ModemState.NotInitialized) { TryInitModem(); return; } if (IsTransitionalState(CurrentModemState) && ModemStateTimeouter.IsTimedOut()) { NihLog.Write(NihLog.Level.Error, "Modem error. Timed out during " + CurrentModemState); CurrentModemState = ModemState.Error; return; } if (CurrentModemState == ModemState.Idle && _lastModemKeepAlive.IsTimedOut()) { // Send keepalive WriteToModem("AT\r"); CurrentModemState = ModemState.KeepAliveAwaitingResponse; return; } if (CurrentModemState == ModemState.Error) { NihLog.Write(NihLog.Level.Debug, "Reenumerating modem..."); UninitModem(); return; } if (_outSmses.Count != 0 && CurrentModemState == ModemState.Idle) { SendSmsNow(); return; } }
private void DoAnswer() { Modem peer = null; if (this.Answer(this, ref peer)) { lock (this._StateLock) { this._Peer = peer; this._State = ModemState.Data; this._Ringing = false; } } }
private void DoDial(string phoneNumber) { Modem peer = null; ConnectResult result = this.Dial(this, phoneNumber, ref peer); if (result == ConnectResult.Connect && peer != null) { peer.OnOOBReceived(OOBSignal.Ring); } Thread.Sleep(1000); switch (result) { case ConnectResult.Connect: this.ChannelWrite(ConnectMessage); lock (this._StateLock) { this._Peer = peer; this._State = ModemState.Data; } break; case ConnectResult.NoDialtone: this.ChannelWrite(NoDialtoneMessage); break; case ConnectResult.NoAnswer: this.ChannelWrite(NoAnswerMessage); break; case ConnectResult.Busy: this.ChannelWrite(BusyMessage); break; } }
private void DoHangup() { Modem peer; lock (this._StateLock) { peer = this._Peer; this._Peer = null; this._State = ModemState.Command; } if (peer != null) { peer.ChannelBreak(); this.Hangup(this); } }
private void OnDataReceived(byte[] bytes, int offset, int count) { ModemState state; bool commandecho; StringBuilder commandsb; lock (this._StateLock) { commandsb = this._CommandBuffer; this._CommandBuffer = null; if (commandsb == null) commandsb = new StringBuilder(); int now = Environment.TickCount; state = this._State; commandecho = this._CommandEcho; switch (state) { case ModemState.Data: if ((now - this._LastDataTime) >= EscapePauseInterval) state = ModemState.DataPause; break; case ModemState.DataPPP: if ((now - this._LastDataTime) >= EscapePauseInterval) state = ModemState.Command; break; } if (state == ModemState.Data && (now - this._LastDataTime) >= EscapePauseInterval) { state = ModemState.DataPause; } this._LastDataTime = now; } int x, limit; for (x = offset, limit = offset + count; x < limit; x++) { byte b = bytes[x]; switch (state) { case ModemState.Data: break; case ModemState.DataPause: case ModemState.DataP: if (b == (byte)'+') state++; else state = ModemState.Data; break; case ModemState.DataPP: case ModemState.DataPPP: if (b == (byte)'+') state = ModemState.DataPPP; else state = ModemState.Data; break; case ModemState.Command: if (b == (byte)'A') state = ModemState.CommandA; break; case ModemState.CommandA: switch (b) { case (byte)'A': break; case (byte)'T': state = ModemState.CommandAT; break; default: state = ModemState.Command; break; } break; case ModemState.CommandAT: if (b == (byte)'\r' || b == (byte)'\n') { // echo command buffer before processing command, in case it generates its own output // (mode can only switch from command to data, and only once during this loop) if (commandecho && offset <= x && state >= ModemState.Command && state <= ModemState.CommandAT) { this.ChannelWrite(bytes, offset, (x + 1) - offset); } string command = commandsb.ToString(); commandsb.Length = 0; state = ModemState.Command; lock (this._StateLock) // commit state before DoCommand { this._State = state; this._CommandBuffer = commandsb; } this.DoCommand(command); lock (this._StateLock) // reload state after DoCommand { state = this._State; commandecho = this._CommandEcho; commandsb = this._CommandBuffer; this._CommandBuffer = null; if (commandsb == null) commandsb = new StringBuilder(); } } else if (b != (byte)' ') { commandsb.Append((char)b); } offset = x + 1; break; } //switch(state) } //for(x<limit) // can't switch from data mode to command mode during loop (because [pause] +++ [pause] is only detected before loop), // but it could switch from command mode to data mode (ATO command) if (offset < limit) { if (state >= ModemState.Data && state <= ModemState.DataPPP) { this.TransmitToPeer(bytes, offset, limit - offset); // send data to remote modem } else if (commandecho && state >= ModemState.Command && state <= ModemState.CommandAT) { this.ChannelWrite(bytes, offset, limit - offset); // echo command } } lock (this._StateLock) // commit state { this._State = state; this._CommandBuffer = commandsb; this._LastDataTime = Environment.TickCount; } }
private void OnOOBReceived(OOBSignal signal) { switch (signal) { case OOBSignal.Break: lock (this._StateLock) { if (this._State >= ModemState.Data && this._State <= ModemState.DataPPP) this._State = ModemState.Command; this._Ringing = false; } this.DoHangup(); // let switchboard know call was disconnected break; case OOBSignal.Ring: this._Channel.Break(); // Wildcat hack lock (this._StateLock) { this._Ringing = true; } //this.ChannelWrite(RingMessage); // Wildcat hack: this.ChannelWrite(ResultCode19200); lock (this._StateLock) { this._State = ModemState.Data; } this.DoAnswer(); break; } }
private void Reset() { this._State = ModemState.Command; this._LastDataTime = Environment.TickCount; this._CommandEcho = false; this._Ringing = false; }
private void DoCommand(string command) { Console.WriteLine("[{0}] {1}", this.PhoneNumber, command); for (int x = 0; x < command.Length; ) { switch (command[x++]) { case 'A': lock (this._StateLock) { if (this._Ringing) { this.DoAnswer(); } } break; case 'D': if ((x + 2) <= command.Length && command[x++] == 'T') { this.DoDial(command.Substring(x)); } return; case 'E': if (x < command.Length) { lock (this._StateLock) { switch (command[x++]) { case '0': this._CommandEcho = false; break; case '1': this._CommandEcho = true; break; } } } break; case 'H': if (x < command.Length && command[x++] == '0') { this.DoHangup(); } break; case 'O': lock (this._StateLock) { if (this._Peer != null) this._State = ModemState.Data; } break; case 'Z': lock (this._StateLock) { this.DoHangup(); this.Reset(); } break; } } }