コード例 #1
0
ファイル: modem.go プロジェクト: okushchenko/sms
func GetMessage(messageIndex int) (*message, error) {
	log.Println("GetMessage...")
	status, err := SendCommand(fmt.Sprintf("AT+CMGR=%d\r", messageIndex), true)
	if err != nil {
		return nil, fmt.Errorf("GetMessage: Failed to send command.\n%s", err.Error())
	}
	log.Printf("GetMessage: %#v\n", status)
	regex := regexp.MustCompile(`(?Us)CMGR: "([A-Z ]*)","([+\d]*)",,"([0-9/,:\+]*)"\r\n(.*)\r\n\r\nOK`)
	if regex.MatchString(status) {
		msg := regex.FindStringSubmatch(status)
		messageLabels := msg[1]
		messageSender := msg[2]
		messageDate, _ := time.Parse("06/01/02,15:04:05-07", msg[3])
		var messageBody string
		if regexp.MustCompile(`^[0-9A-F]+$`).MatchString(msg[4]) {
			bytesWritten, _ := hex.DecodeString(msg[4])
			log.Println("GetMessage: bytesWritten =", bytesWritten)
			regex := regexp.MustCompile(`[a-z ]{3}`)
			if regex.MatchString(string(bytesWritten)) {
				log.Printf("GetMessage: Decoding message #%d using plain text", messageIndex)
				messageBody = string(bytesWritten)
			} else {
				log.Printf("GetMessage: Decoding message #%d using Ucs2", messageIndex)
				messageBody, err = pdu.DecodeUcs2(bytesWritten)
				if err != nil {
					log.Printf("GetMessage: Failed to decode message #%d using Ucs2", messageIndex)
				}
			}
		} else {
			messageBody = msg[4]
		}
		log.Printf("GetMessage: %v %#v %#v %v %#v\n", messageIndex, messageLabels, messageSender, messageDate.Format(time.RFC3339), messageBody)
		return &message{
			Labels: messageLabels,
			Date:   messageDate,
			Sender: messageSender,
			Body:   messageBody,
			Index:  messageIndex,
		}, nil
	} else {
		return nil, fmt.Errorf("GetMessage: Failed to parse response: %v", status)
	}
}
コード例 #2
0
ファイル: at.go プロジェクト: evandertino/at
// 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
}
コード例 #3
0
ファイル: sms.go プロジェクト: evandertino/at
// ReadFrom constructs a message from the supplied PDU octets. Returns the number of bytes read.
// Complies with 3GPP TS 23.040.
func (s *Message) ReadFrom(octets []byte) (n int, err error) {
	*s = Message{}
	buf := bytes.NewReader(octets)
	scLen, err := buf.ReadByte()
	n++
	if err != nil {
		return
	}
	if scLen > 12 {
		return 0, ErrIncorrectSize
	}
	addr := make([]byte, scLen)
	off, err := io.ReadFull(buf, addr)
	n += off
	if err != nil {
		return
	}
	s.ServiceCenterAddress.ReadFrom(addr)
	msgType, err := buf.ReadByte()
	n++
	if err != nil {
		return
	}
	n--
	buf.UnreadByte()
	s.Type = MessageType(msgType & 0x03)

	switch s.Type {
	case MessageTypes.Deliver:
		var sms smsDeliver
		off, err2 := sms.FromBytes(octets[1+scLen:])
		n += off
		if err2 != nil {
			return n, err2
		}
		s.MoreMessagesToSend = sms.MoreMessagesToSend
		s.LoopPrevention = sms.LoopPrevention
		s.ReplyPathExists = sms.ReplyPath
		s.UserDataStartsWithHeader = sms.UserDataHeaderIndicator
		s.StatusReportIndication = sms.StatusReportIndication
		s.Address.ReadFrom(sms.OriginatingAddress[1:])
		s.Encoding = Encoding(sms.DataCodingScheme)
		s.ServiceCenterTime.ReadFrom(sms.ServiceCentreTimestamp)
		switch s.Encoding {
		case Encodings.Gsm7Bit:
			s.Text, err = pdu.Decode7Bit(sms.UserData)
			if err != nil {
				return
			}
			s.Text = cutStr(s.Text, int(sms.UserDataLength))
		case Encodings.UCS2:
			s.Text, err = pdu.DecodeUcs2(sms.UserData)
			if err != nil {
				return
			}
		default:
			return 0, ErrUnknownEncoding
		}
	case MessageTypes.Submit:
		var sms smsSubmit
		off, err2 := sms.FromBytes(octets[1+scLen:])
		n += off
		if err2 != nil {
			return n, err2
		}
		s.RejectDuplicates = sms.RejectDuplicates

		switch s.VPFormat {
		case ValidityPeriodFormats.Absolute, ValidityPeriodFormats.Enhanced:
			return n, ErrNonRelative
		default:
			s.VPFormat = ValidityPeriodFormat(sms.ValidityPeriodFormat)
		}

		s.ReplyPathExists = sms.ReplyPath
		s.UserDataStartsWithHeader = sms.UserDataHeaderIndicator
		s.StatusReportRequest = sms.StatusReportRequest
		s.Address.ReadFrom(sms.DestinationAddress[1:])
		s.Encoding = Encoding(sms.DataCodingScheme)

		if s.VPFormat != ValidityPeriodFormats.FieldNotPresent {
			s.VP.ReadFrom(sms.ValidityPeriod)
		}

		switch s.Encoding {
		case Encodings.Gsm7Bit:
			s.Text, err = pdu.Decode7Bit(sms.UserData)
			if err != nil {
				return
			}
			s.Text = cutStr(s.Text, int(sms.UserDataLength))
		case Encodings.UCS2:
			s.Text, err = pdu.DecodeUcs2(sms.UserData)
			if err != nil {
				return
			}
		default:
			return 0, ErrUnknownEncoding
		}
	default:
		return n, ErrUnknownMessageType
	}

	return
}