// Init invokes a set of methods that will make the initial setup of the modem. func (p *DefaultProfile) Init(d *Device) (err error) { p.dev = d p.dev.Send(NoopCmd) // kinda flush if err = p.COPS(true, true); err != nil { return errors.New("at init: unable to adjust the format of operator's name") } var info *SystemInfoReport if info, err = p.SYSINFO(); err != nil { return errors.New("at init: unable to read system info") } p.dev.State = &DeviceState{ ServiceState: info.ServiceState, ServiceDomain: info.ServiceDomain, RoamingState: info.RoamingState, SystemMode: info.SystemMode, SystemSubmode: info.SystemSubmode, SimState: info.SimState, } if p.dev.State.OperatorName, err = p.OperatorName(); err != nil { return errors.New("at init: unable to read operator's name") } if p.dev.State.ModelName, err = p.ModelName(); err != nil { return errors.New("at init: unable to read modem's model name") } if p.dev.State.IMEI, err = p.IMEI(); err != nil { return errors.New("at init: unable to read modem's IMEI code") } if err = p.CMGF(false); err != nil { return errors.New("at init: unable to switch message format to PDU") } if err = p.CPMS(MemoryTypes.NvRAM, MemoryTypes.NvRAM, MemoryTypes.NvRAM); err != nil { return errors.New("at init: unable to set messages storage") } if err = p.CNMI(1, 1, 0, 0, 0); err != nil { return errors.New("at init: unable to turn on message notifications") } var octets map[uint64][]byte if octets, err = p.CMGL(MessageFlags.Any); err != nil { return errors.New("at init: unable to check message inbox") } for n, oct := range octets { var msg sms.Message if _, err := msg.ReadFrom(oct); err != nil { return errors.New("at init: error while parsing message inbox") } if err := p.CMGD(n, DeleteOptions.Index); err != nil { return errors.New("at init: error while cleaning message inbox") } d.messages <- &msg } return nil }
// 处理短信PUD字符串. // s 串口接收到的PDU字符串. func (g *Gsm) handleSMS(s string) { b, err := hex.DecodeString(s) if nil != err { g.mLogger.Error(`GSMSMS: Decode sms hex string error "%v"`, err) return } var msg sms.Message _, err = msg.ReadFrom(b) if err != nil { g.mLogger.Error(`GSMSMS: Decode sms message error "%v"`, err) return } select { case g.mChanSMS <- &msg: default: g.mLogger.Debug(`GSMSMS: Drop [%v]"%v"`, string(msg.Address), msg.Text) } }
// handleReport detects and parses a report from the notification port represented // as a string. The parsed values may change the inner state or be sent over out channels. func (d *Device) handleReport(str string) (err error) { report := Reports.Resolve(str) str = strings.TrimSpace(strings.TrimPrefix(str, report.ID)) switch report { case Reports.Message: var report messageReport if err = report.Parse(str); err != nil { return } var octets []byte octets, err = d.Commands.CMGR(report.Index) if err != nil { return } if err = d.Commands.CMGD(report.Index, DeleteOptions.Index); err != nil { return } var msg sms.Message if _, err = msg.ReadFrom(octets); err != nil { return } d.messages <- &msg case Reports.Ussd: var ussd ussdReport if err = ussd.Parse(str); err != nil { return } var text string if ussd.Enc == Encodings.UCS2 { text, err = pdu.DecodeUcs2(ussd.Octets) if err != nil { return } } else if ussd.Enc == Encodings.Gsm7Bit { text, err = pdu.Decode7Bit(ussd.Octets) if err != nil { return } } else { return ErrUnknownEncoding } d.ussd <- Ussd(text) case Reports.SignalStrength: var rssi signalStrengthReport if err = rssi.Parse(str); err != nil { return } if d.State.SignalStrength != int(rssi) { d.State.SignalStrength = int(rssi) d.updated <- struct{}{} } case Reports.Mode: var report modeReport if err = report.Parse(str); err != nil { return } var updated bool if d.State.SystemMode != report.Mode { d.State.SystemMode = report.Mode updated = true } if d.State.SystemSubmode != report.Submode { d.State.SystemSubmode = report.Submode updated = true } if updated { d.updated <- struct{}{} } case Reports.ServiceState: var report serviceStateReport if err = report.Parse(str); err != nil { return } if d.State.ServiceState != Opt(report) { d.State.ServiceState = Opt(report) d.updated <- struct{}{} } case Reports.SimState: var report simStateReport if err = report.Parse(str); err != nil { return } if d.State.SimState != Opt(report) { d.State.SimState = Opt(report) d.updated <- struct{}{} } case Reports.BootHandshake: var token bootHandshakeReport if err = token.Parse(str); err != nil { return } if err = d.Commands.BOOT(uint64(token)); err != nil { return } case Reports.Stin: // ignore. what is this btw? default: switch FinalResults.Resolve(str) { case FinalResults.Noop, FinalResults.NotSupported, FinalResults.Timeout: // ignore default: return errors.New("at: unknown report: " + str) } } return }