Beispiel #1
0
func GetBalance(ussdRequest string) (float64, error) {
	log.Println("GetBalance...")
	//re-set encoding here?
	//m.SendCommand("AT+CSCS=\"GSM\"\r", true)
	//TODO: Is it necessery to run AT+CMGF=0 ???
	SendCommand("AT+CMGF=0\r", true)
	SendCommand("AT^USSDMODE=1\r", true)
	request := strings.ToUpper(fmt.Sprintf("%x", pdu.Encode7Bit(ussdRequest)))
	_, err = SendCommand(fmt.Sprintf("AT+CUSD=1,\"%s\",15\r", request), true)
	if err != nil {
		return 0.0, err
	}
	status, err := WaitForOutput(10, "15\r\n")
	regex := regexp.MustCompile(`\+CUSD: \d{1},\"([a-zA-Z0-9]*)\",\d*`)
	if regex.MatchString(status) {
		balanceRaw := regex.FindStringSubmatch(status)[1]
		bytesWritten, _ := hex.DecodeString(balanceRaw)
		log.Println("Before decode", bytesWritten)
		balanceRaw, _ = pdu.Decode7Bit(bytesWritten)
		log.Println("After decode", balanceRaw)
		balanceParsed := regexp.MustCompile(`\d+\.\d+`).FindString(balanceRaw)
		if balanceParsed == "" {
			return 0.0, fmt.Errorf("GetBalance: Failed to find balance string in \"%s\"", balanceRaw)
		}
		balance, err := strconv.ParseFloat(balanceParsed, 64)
		if err != nil {
			return 0.0, fmt.Errorf("GetBalance: Failed to convert to float64 \"%s\"", balanceRaw)
		}
		return balance, nil
	}
	if err != nil {
		return 0.0, err
	}
	return 0.0, errors.New("GetBalace: Failed to get balance.")
}
Beispiel #2
0
// Encode converts the query string into bytes according to the
// specified encoding.
func (u *Ussd) Encode(enc Encoding) ([]byte, error) {
	switch enc {
	case Encodings.Gsm7Bit:
		return pdu.Encode7Bit(u.String()), nil
	case Encodings.UCS2:
		return pdu.EncodeUcs2(u.String()), nil
	default:
		return nil, ErrUnknownEncoding
	}
}
Beispiel #3
0
// Test USSD queries, the result will be reported asynchroniously.
func TestUssd(t *testing.T) {
	err := openDevice()
	if !assert.NoError(t, err) {
		return
	}
	defer func() {
		dev.Close()
	}()
	err = dev.Commands.CUSD(UssdResultReporting.Enable, pdu.Encode7Bit(BalanceUSSD), Encodings.Gsm7Bit)
	if !assert.NoError(t, err) {
		return
	}
	waitDevice(10)
}
Beispiel #4
0
// SendUSSD sends an USSD request, the encoding and other parameters are default.
func (d *Device) SendUSSD(req string) (err error) {
	err = d.Commands.CUSD(UssdResultReporting.Enable, pdu.Encode7Bit(req), Encodings.Gsm7Bit)
	return
}
Beispiel #5
0
// PDU serializes the message into octets ready to be transferred.
// Returns the number of TPDU bytes in the produced PDU.
// Complies with 3GPP TS 23.040.
func (s *Message) PDU() (int, []byte, error) {
	var buf bytes.Buffer
	if len(s.ServiceCenterAddress) < 1 {
		buf.WriteByte(0x00) // SMSC info length
	} else {
		_, octets, err := s.ServiceCenterAddress.PDU()
		if err != nil {
			return 0, nil, err
		}
		buf.WriteByte(byte(len(octets)))
		buf.Write(octets)
	}

	switch s.Type {
	case MessageTypes.Deliver:
		var sms smsDeliver
		sms.MessageTypeIndicator = byte(s.Type)
		sms.MoreMessagesToSend = s.MoreMessagesToSend
		sms.LoopPrevention = s.LoopPrevention
		sms.ReplyPath = s.ReplyPathExists
		sms.UserDataHeaderIndicator = s.UserDataStartsWithHeader
		sms.StatusReportIndication = s.StatusReportIndication

		addrLen, addr, err := s.Address.PDU()
		if err != nil {
			return 0, nil, err
		}
		var addrBuf bytes.Buffer
		addrBuf.WriteByte(byte(addrLen))
		addrBuf.Write(addr)
		sms.OriginatingAddress = addrBuf.Bytes()

		sms.ProtocolIdentifier = 0x00 // Short Message Type 0
		sms.DataCodingScheme = byte(s.Encoding)
		sms.ServiceCentreTimestamp = s.ServiceCenterTime.PDU()

		var userData []byte
		if s.Encoding == Encodings.Gsm7Bit {
			userData = pdu.Encode7Bit(s.Text)
			sms.UserDataLength = byte(len(s.Text))
		} else if s.Encoding == Encodings.UCS2 {
			userData = pdu.EncodeUcs2(s.Text)
			sms.UserDataLength = byte(len(userData))
		} else {
			return 0, nil, ErrUnknownEncoding
		}

		sms.UserDataLength = byte(len(userData))
		sms.UserData = userData
		n, err := buf.Write(sms.Bytes())
		if err != nil {
			return 0, nil, err
		}
		return n, buf.Bytes(), nil
	case MessageTypes.Submit:
		var sms smsSubmit
		sms.MessageTypeIndicator = byte(s.Type)
		sms.RejectDuplicates = s.RejectDuplicates
		sms.ValidityPeriodFormat = byte(s.VPFormat)
		sms.ReplyPath = s.ReplyPathExists
		sms.UserDataHeaderIndicator = s.UserDataStartsWithHeader
		sms.StatusReportRequest = s.StatusReportRequest
		sms.MessageReference = s.MessageReference

		addrLen, addr, err := s.Address.PDU()
		if err != nil {
			return 0, nil, err
		}
		var addrBuf bytes.Buffer
		addrBuf.WriteByte(byte(addrLen))
		addrBuf.Write(addr)
		sms.DestinationAddress = addrBuf.Bytes()

		sms.ProtocolIdentifier = 0x00 // Short Message Type 0
		sms.DataCodingScheme = byte(s.Encoding)

		switch s.VPFormat {
		case ValidityPeriodFormats.Relative:
			sms.ValidityPeriod = byte(s.VP.Octet())
		case ValidityPeriodFormats.Absolute, ValidityPeriodFormats.Enhanced:
			return 0, nil, ErrNonRelative
		}

		var userData []byte
		if s.Encoding == Encodings.Gsm7Bit {
			userData = pdu.Encode7Bit(s.Text)
			sms.UserDataLength = byte(len(s.Text))
		} else if s.Encoding == Encodings.UCS2 {
			userData = pdu.EncodeUcs2(s.Text)
			sms.UserDataLength = byte(len(userData))
		} else {
			return 0, nil, ErrUnknownEncoding
		}

		sms.UserData = userData
		n, err := buf.Write(sms.Bytes())
		if err != nil {
			return 0, nil, err
		}
		return n, buf.Bytes(), nil
	default:
		return 0, nil, ErrUnknownMessageType
	}
}
Beispiel #6
0
// Gsm7Bit encodes USSD query into GSM 7-Bit packed octets.
func (u USSD) Gsm7Bit() []byte {
	return pdu.Encode7Bit(string(u))
}