Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ smsSubmitGsm7 := Message{
Type: MessageTypes.Submit,
Address: "+79261234567",
ServiceCenterAddress: "+79262000331",
VP: ValidityPeriod(time.Hour * 24 * 4),
VP: RelativeValidityPeriod(time.Hour * 24 * 4),
VPFormat: ValidityPeriodFormats.Relative,
}
n, octets, err := smsSubmitGsm7.PDU()
Expand Down
2 changes: 1 addition & 1 deletion at.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ func (d *Device) SendSMS(text string, address sms.PhoneNumber) (err error) {
Encoding: sms.Encodings.Gsm7Bit,
Address: address,
VPFormat: sms.ValidityPeriodFormats.Relative,
VP: sms.ValidityPeriod(24 * time.Hour * 4),
VP: sms.RelativeValidityPeriod(24 * time.Hour * 4),
}

if !pdu.Is7BitEncodable(text) {
Expand Down
41 changes: 29 additions & 12 deletions sms/sms.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ var (
ErrUnknownEncoding = errors.New("sms: unsupported encoding")
ErrUnknownMessageType = errors.New("sms: unsupported message type")
ErrIncorrectSize = errors.New("sms: decoded incorrect size of field")
ErrNonRelative = errors.New("sms: non-relative validity period support is not implemented yet")
ErrLongEnhancedVpNotSupported = errors.New("sms: extended functionality indicator for enhanced validity period is not supported")
ErrUnknownEnhancedVpReservedBits = errors.New("sms: unknown reserved bits for enhanced validity period were set")
ErrUnknownVpf = errors.New("sms: unknown validity period format")
ErrIncorrectUserDataHeaderLength = errors.New("sms: incorrect user data header length ")
ErrUnsupportedTypeOfNumber = errors.New("sms: unsupported type-of-number")
)
Expand All @@ -26,7 +28,9 @@ var (
type Message struct {
Type MessageType
Encoding Encoding
VP ValidityPeriod
VP RelativeValidityPeriod
AbsoluteVP AbsoluteValidityPeriod
EnhancedVP EnhancedValidityPeriod
VPFormat ValidityPeriodFormat
ServiceCenterTime Timestamp
DischargeTime Timestamp
Expand Down Expand Up @@ -151,10 +155,17 @@ func (s *Message) encodeSubmit(buf *bytes.Buffer) (n int, err error) {
sms.DataCodingScheme = byte(s.Encoding)

switch s.VPFormat {
case ValidityPeriodFormats.FieldNotPresent:
sms.ValidityPeriod = make([]byte, 0)
case ValidityPeriodFormats.Relative:
sms.ValidityPeriod = byte(s.VP.Octet())
case ValidityPeriodFormats.Absolute, ValidityPeriodFormats.Enhanced:
return 0, ErrNonRelative
sms.ValidityPeriod = []byte{s.VP.Octet()}
case ValidityPeriodFormats.Absolute:
sms.ValidityPeriod = s.AbsoluteVP.PDU()
case ValidityPeriodFormats.Enhanced:
sms.ValidityPeriod, err = s.EnhancedVP.PDU()
if err != nil {
return 0, err
}
}

sms.UserData, sms.UserDataLength, err = s.encodedUserData()
Expand Down Expand Up @@ -272,11 +283,20 @@ func (s *Message) decodeSubmit(data []byte) (n int, err error) {
}
s.RejectDuplicates = sms.RejectDuplicates

switch ValidityPeriodFormat(sms.ValidityPeriodFormat) {
case ValidityPeriodFormats.Absolute, ValidityPeriodFormats.Enhanced:
return n, ErrNonRelative
s.VPFormat = ValidityPeriodFormat(sms.ValidityPeriodFormat)
switch s.VPFormat {
case ValidityPeriodFormats.FieldNotPresent:
case ValidityPeriodFormats.Absolute:
s.AbsoluteVP.ReadFrom(sms.ValidityPeriod)
case ValidityPeriodFormats.Relative:
s.VP.ReadFrom(sms.ValidityPeriod[0])
case ValidityPeriodFormats.Enhanced:
err = s.EnhancedVP.ReadFrom(sms.ValidityPeriod)
if err != nil {
return n, err
}
default:
s.VPFormat = ValidityPeriodFormat(sms.ValidityPeriodFormat)
return n, ErrUnknownVpf
}

s.MessageReference = sms.MessageReference
Expand All @@ -286,9 +306,6 @@ func (s *Message) decodeSubmit(data []byte) (n int, err error) {
s.Address.ReadFrom(sms.DestinationAddress[1:])
s.Encoding = Encoding(sms.DataCodingScheme)

if s.VPFormat != ValidityPeriodFormats.FieldNotPresent {
s.VP.ReadFrom(sms.ValidityPeriod)
}
err = s.decodeUserData(sms.UserData, sms.UserDataLength)
return n, err
}
Expand Down
29 changes: 22 additions & 7 deletions sms/sms_submit.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type smsSubmit struct {
DestinationAddress []byte
ProtocolIdentifier byte
DataCodingScheme byte
ValidityPeriod byte
ValidityPeriod []byte
UserDataLength byte
UserData []byte
}
Expand All @@ -44,9 +44,7 @@ func (s *smsSubmit) Bytes() []byte {
buf.Write(s.DestinationAddress)
buf.WriteByte(s.ProtocolIdentifier)
buf.WriteByte(s.DataCodingScheme)
if ValidityPeriodFormat(s.ValidityPeriodFormat) != ValidityPeriodFormats.FieldNotPresent {
buf.WriteByte(s.ValidityPeriod)
}
buf.Write(s.ValidityPeriod)
buf.WriteByte(s.UserDataLength)
buf.Write(s.UserData)
return buf.Bytes()
Expand Down Expand Up @@ -105,13 +103,30 @@ func (s *smsSubmit) FromBytes(octets []byte) (n int, err error) { //nolint:funle
if err != nil {
return
}
if ValidityPeriodFormat(s.ValidityPeriodFormat) != ValidityPeriodFormats.FieldNotPresent {
s.ValidityPeriod, err = buf.ReadByte()
n++

switch ValidityPeriodFormat(s.ValidityPeriodFormat) {
case ValidityPeriodFormats.FieldNotPresent:
s.ValidityPeriod = make([]byte, 0)
case ValidityPeriodFormats.Relative:
s.ValidityPeriod = make([]byte, 1)
off, err = io.ReadFull(buf, s.ValidityPeriod)
n += off
if err != nil {
return
}
case ValidityPeriodFormats.Absolute:
fallthrough
case ValidityPeriodFormats.Enhanced:
s.ValidityPeriod = make([]byte, 7)
off, err = io.ReadFull(buf, s.ValidityPeriod)
n += off
if err != nil {
return
}
default:
return
}

s.UserDataLength, err = buf.ReadByte()
n++
if err != nil {
Expand Down
109 changes: 105 additions & 4 deletions sms/sms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ var (
pduSubmitGsm7 = "07919762020033F111000B919762995696F00000AA066379180E8200"
pduSubmitGsm7_EnhancedTpVp = "05915155010009010891515511110000420300000000001e547" +
"47a0e9a36a72074780e9a81e6e5f1db4d9e83e86f103b6d2f03"
pduSubmitGsm7_EnhancedTpVp2 = "05915155020009000891515522220000010000000000001f54" +
"747a0e9a36a7a0f41c640fb3d36490f92d07c940edb4bb4e2fcf1b"
pduSubmitGsm7_AbsoluteTpVp = "059151550100190008915155111100001010103295953246cfb" +
"a1ce42cc3c3ecf2bc0c32cbd36537790eba87dd74101d9d9e83a6cd29485c36bfe565900c068" +
"bb560b1162c0692cd74b59cae960355a9c3554d47ab01"

pduDeliverGsm7_2 = "0791551010010201040D91551699296568F80011719022124215293DD4B71C5E26BF" +
"41D3E6145476D3E5E573BD0C82BF40B59A2D96CBE564351BCE8603A164319D8CA6ABD540E432482673C172AED82DE502"

Expand Down Expand Up @@ -61,7 +67,7 @@ var (
Type: MessageTypes.Submit,
Address: "+79269965690",
ServiceCenterAddress: "+79168999100",
VP: ValidityPeriod(time.Hour * 24 * 4),
VP: RelativeValidityPeriod(time.Hour * 24 * 4),
VPFormat: ValidityPeriodFormats.Relative,
}
smsSubmitGsm7 = Message{
Expand All @@ -70,15 +76,46 @@ var (
Type: MessageTypes.Submit,
Address: "+79269965690",
ServiceCenterAddress: "+79262000331",
VP: ValidityPeriod(time.Hour * 24 * 4),
VP: RelativeValidityPeriod(time.Hour * 24 * 4),
VPFormat: ValidityPeriodFormats.Relative,
}
smsSubmitGsm7_AbsoluteTpVp = Message{
Text: "Our Nepalese friends want this SMS before 2001-01-01 23:59:59 UTC+5:45",
Encoding: Encodings.Gsm7Bit,
Type: MessageTypes.Submit,
Address: "+15551111",
ServiceCenterAddress: "+15551000",
AbsoluteVP: AbsoluteValidityPeriod(parseTimestamp("2001-01-01T23:59:59+05:45")),
VPFormat: ValidityPeriodFormats.Absolute,
}
smsSubmitGsm7_EnhancedTpVp = Message{
Text: "This SMS has 3 seconds to live",
Encoding: Encodings.Gsm7Bit,
Type: MessageTypes.Submit,
Address: "+15551111",
ServiceCenterAddress: "+15551000",
VPFormat: ValidityPeriodFormats.Enhanced,
EnhancedVP: EnhancedValidityPeriod{
ExtensionBit: false,
SingleShotSm: true,
EnhancedFormat: EnhancedValidityPeriodFormats.RelativeInteger,
RelativeIntegerVP: 3,
},
MessageReference: 1,
}
smsSubmitGsm7_EnhancedTpVp2 = Message{
Text: "This SMS is valid for 2 minutes",
Encoding: Encodings.Gsm7Bit,
Type: MessageTypes.Submit,
Address: "+15552222",
ServiceCenterAddress: "+15552000",
VPFormat: ValidityPeriodFormats.Enhanced,
EnhancedVP: EnhancedValidityPeriod{
ExtensionBit: false,
SingleShotSm: false,
EnhancedFormat: EnhancedValidityPeriodFormats.Relative,
RelativeVP: 0,
},
}
smsReport = Message{
Type: MessageTypes.StatusReport,
Expand All @@ -101,6 +138,14 @@ func parseTimestamp(timetamp string) Timestamp {
return Timestamp(date)
}

func asBytes(str string) []byte {
bytes, err := util.Bytes(str)
if err != nil {
panic(err)
}
return bytes
}

func TestSmsDeliverReadFromUCS2(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -185,14 +230,40 @@ func TestSmsSubmitReadFromGsm7(t *testing.T) {
assert.Equal(t, smsSubmitGsm7, msg)
}

func TestSmsSubmitReadFromGsm7_AbsoluteTpVp(t *testing.T) {
t.Parallel()

var msg Message
data, err := util.Bytes(pduSubmitGsm7_AbsoluteTpVp)
require.NoError(t, err)
n, err := msg.ReadFrom(data)
require.NoError(t, err)
assert.Equal(t, n, len(data))
assert.Equal(t, smsSubmitGsm7_AbsoluteTpVp, msg)
}

func TestSmsSubmitReadFromGsm7_EnhancedTpVp(t *testing.T) {
t.Parallel()

var msg Message
data, err := util.Bytes(pduSubmitGsm7_EnhancedTpVp)
require.NoError(t, err)
_, err = msg.ReadFrom(data)
assert.Equal(t, err, ErrNonRelative)
n, err := msg.ReadFrom(data)
require.NoError(t, err)
assert.Equal(t, n, len(data))
assert.Equal(t, smsSubmitGsm7_EnhancedTpVp, msg)
}

func TestSmsSubmitReadFromGsm7_EnhancedTpVp2(t *testing.T) {
t.Parallel()

var msg Message
data, err := util.Bytes(pduSubmitGsm7_EnhancedTpVp2)
require.NoError(t, err)
n, err := msg.ReadFrom(data)
require.NoError(t, err)
assert.Equal(t, n, len(data))
assert.Equal(t, smsSubmitGsm7_EnhancedTpVp2, msg)
}

func TestSmsSubmitPduUCS2(t *testing.T) {
Expand All @@ -217,6 +288,36 @@ func TestSmsSubmitPduGsm7(t *testing.T) {
assert.Equal(t, data, octets)
}

func TestSmsSubmitPduGsm7_AbsoluteTpVp(t *testing.T) {
t.Parallel()

n, octets, err := smsSubmitGsm7_AbsoluteTpVp.PDU()
require.NoError(t, err)
data := asBytes(pduSubmitGsm7_AbsoluteTpVp)
assert.Equal(t, len(data) - 6, n)
assert.Equal(t, data, octets)
}

func TestSmsSubmitPduGsm7_EnhancedTpVp(t *testing.T) {
t.Parallel()

n, octets, err := smsSubmitGsm7_EnhancedTpVp.PDU()
require.NoError(t, err)
data := asBytes(pduSubmitGsm7_EnhancedTpVp)
assert.Equal(t, len(data) - 6, n)
assert.Equal(t, data, octets)
}

func TestSmsSubmitPduGsm7_EnhancedTpVp2(t *testing.T) {
t.Parallel()

n, octets, err := smsSubmitGsm7_EnhancedTpVp2.PDU()
require.NoError(t, err)
data := asBytes(pduSubmitGsm7_EnhancedTpVp2)
assert.Equal(t, len(data) - 6, n)
assert.Equal(t, data, octets)
}

func TestSmsStatusReport(t *testing.T) {
t.Parallel()

Expand Down
Loading
Loading