示例#1
0
        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;
            }
        }
示例#2
0
 private bool IsTransitionalState(ModemState ms)
 {
     return(ms == ModemState.Initializing ||
            ms == ModemState.SendingSMS ||
            ms == ModemState.PowerUp ||
            ms == ModemState.KeepAliveAwaitingResponse);
 }
示例#3
0
        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();
                }
            }
        }
示例#4
0
 void UninitModem()
 {
     if (modemPort != null)
     {
         modemPort.Dispose();
     }
     modemPort         = null;
     CurrentModemState = ModemState.NotInitialized;
 }
示例#5
0
 private void RecvTimeOut(object nullObj)
 {
     if (State == ModemState.Receving)
     {
         State = ModemState.Ready;
         RSSI  = -1;
         if (LostPackets == int.MaxValue)
         {
             LostPackets = 0;
         }
         LostPackets++;
         sendNextPacket();
     }
 }
示例#6
0
        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;
        }
示例#7
0
        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;
        }
示例#8
0
        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();
            }
        }
示例#9
0
        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;
        }
示例#10
0
        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;
            }
        }
示例#11
0
        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;
                }
            }
        }
示例#12
0
        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;
            }
        }
示例#13
0
        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);
            }
        }
示例#14
0
        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;
            }
        }
示例#15
0
        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;
            }
        }
示例#16
0
        private void Reset()
        {
            this._State = ModemState.Command;

            this._LastDataTime = Environment.TickCount;
            this._CommandEcho = false;
            this._Ringing = false;
        }
示例#17
0
        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;
                }
            }
        }