func TestServer(t *testing.T) { s := NewServer() defer s.Close() c, err := net.Dial("tcp", s.Addr()) if err != nil { t.Fatal(err) } defer c.Close() rw := newConn(c) // bind p := pdu.NewBindTransmitter() f := p.Fields() f.Set(pdufield.SystemID, "client") f.Set(pdufield.Password, "secret") f.Set(pdufield.InterfaceVersion, 0x34) if err = rw.Write(p); err != nil { t.Fatal(err) } // bind resp resp, err := rw.Read() if err != nil { t.Fatal(err) } id, ok := resp.Fields()[pdufield.SystemID] if !ok { t.Fatalf("missing system_id field: %#v", resp) } if id.String() != "smpptest" { t.Fatalf("unexpected system_id: want smpptest, have %q", id) } // submit_sm p = pdu.NewSubmitSM() f = p.Fields() f.Set(pdufield.SourceAddr, "foobar") f.Set(pdufield.DestinationAddr, "bozo") f.Set(pdufield.ShortMessage, pdutext.Latin1("Lorem ipsum")) if err = rw.Write(p); err != nil { t.Fatal(err) } // same submit_sm r, err := rw.Read() if err != nil { t.Fatal(err) } want, have := *p.Header(), *r.Header() if want != have { t.Fatalf("unexpected header: want %#v, have %#v", want, have) } for k, v := range p.Fields() { vv, exists := r.Fields()[k] if !exists { t.Fatalf("unexpected fields: want %#v, have %#v", p.Fields(), r.Fields()) } if !bytes.Equal(v.Bytes(), vv.Bytes()) { t.Fatalf("unexpected field data: want %#v, have %#v", v, vv) } } }
// SubmitLongMsg sends a long message (more than 140 bytes) // and returns and updates the given sm with the response status. // It returns the same sm object. func (t *Transmitter) SubmitLongMsg(sm *ShortMessage) (*ShortMessage, error) { maxLen := 134 // 140-6 (UDH) rawMsg := sm.Text.Encode() countParts := int((len(rawMsg)-1)/maxLen) + 1 ri := uint8(t.r.Intn(128)) UDHHeader := make([]byte, 6) UDHHeader[0] = 5 UDHHeader[1] = 0 UDHHeader[2] = 3 UDHHeader[3] = ri UDHHeader[4] = uint8(countParts) for i := 0; i < countParts; i++ { UDHHeader[5] = uint8(i + 1) p := pdu.NewSubmitSM() f := p.Fields() f.Set(pdufield.SourceAddr, sm.Src) f.Set(pdufield.DestinationAddr, sm.Dst) if i != countParts-1 { f.Set(pdufield.ShortMessage, pdutext.Raw(append(UDHHeader, rawMsg[i*maxLen:(i+1)*maxLen]...))) } else { f.Set(pdufield.ShortMessage, pdutext.Raw(append(UDHHeader, rawMsg[i*maxLen:]...))) } f.Set(pdufield.RegisteredDelivery, uint8(sm.Register)) if sm.Validity != time.Duration(0) { f.Set(pdufield.ValidityPeriod, convertValidity(sm.Validity)) } f.Set(pdufield.ServiceType, sm.ServiceType) f.Set(pdufield.SourceAddrTON, sm.SourceAddrTON) f.Set(pdufield.SourceAddrNPI, sm.SourceAddrNPI) f.Set(pdufield.DestAddrTON, sm.DestAddrTON) f.Set(pdufield.DestAddrNPI, sm.DestAddrNPI) f.Set(pdufield.ESMClass, 0x40) f.Set(pdufield.ProtocolID, sm.ProtocolID) f.Set(pdufield.PriorityFlag, sm.PriorityFlag) f.Set(pdufield.ScheduleDeliveryTime, sm.ScheduleDeliveryTime) f.Set(pdufield.ReplaceIfPresentFlag, sm.ReplaceIfPresentFlag) f.Set(pdufield.SMDefaultMsgID, sm.SMDefaultMsgID) f.Set(pdufield.DataCoding, uint8(sm.Text.Type())) resp, err := t.do(p) if err != nil { return nil, err } sm.resp.Lock() sm.resp.p = resp.PDU sm.resp.Unlock() if id := resp.PDU.Header().ID; id != pdu.SubmitSMRespID { return sm, fmt.Errorf("unexpected PDU ID: %s", id) } if s := resp.PDU.Header().Status; s != 0 { return sm, s } if resp.Err != nil { return sm, resp.Err } } return sm, nil }
// Submit sends a short message and returns and updates the given // sm with the response status. It returns the same sm object. func (t *Transmitter) Submit(sm *ShortMessage) (*ShortMessage, error) { if len(sm.DstList) > 0 || len(sm.DLs) > 0 { // if we have a single destination address add it to the list if sm.Dst != "" { sm.DstList = append(sm.DstList, sm.Dst) } p := pdu.NewSubmitMulti() return t.submitMsgMulti(sm, p, uint8(sm.Text.Type())) } p := pdu.NewSubmitSM() return t.submitMsg(sm, p, uint8(sm.Text.Type())) }
// Submit sends a short message and returns and updates the given // sm with the response status. It returns the same sm object. func (t *Transmitter) Submit(sm *ShortMessage) (*ShortMessage, error) { p := pdu.NewSubmitSM() f := p.Fields() f.Set(pdufield.SourceAddr, sm.Src) f.Set(pdufield.DestinationAddr, sm.Dst) f.Set(pdufield.ShortMessage, sm.Text) f.Set(pdufield.RegisteredDelivery, uint8(sm.Register)) resp, err := t.do(p) if err != nil { return nil, err } sm.resp.Lock() sm.resp.p = resp.PDU sm.resp.Unlock() if id := resp.PDU.Header().ID; id != pdu.SubmitSMRespID { return sm, fmt.Errorf("unexpected PDU ID: %s", id) } if s := resp.PDU.Header().Status; s != 0 { return sm, s } return sm, resp.Err }
// Submit sends a short message and returns and updates the given // sm with the response status. It returns the same sm object. func (t *Transmitter) Submit(sm *ShortMessage) (*ShortMessage, error) { p := pdu.NewSubmitSM() f := p.Fields() f.Set(pdufield.SourceAddr, sm.Src) f.Set(pdufield.DestinationAddr, sm.Dst) f.Set(pdufield.ShortMessage, sm.Text) f.Set(pdufield.RegisteredDelivery, uint8(sm.Register)) // Check if the message has validity set. if sm.Validity != time.Duration(0) { f.Set(pdufield.ValidityPeriod, convertValidity(sm.Validity)) } f.Set(pdufield.ServiceType, sm.ServiceType) f.Set(pdufield.SourceAddrTON, sm.SourceAddrTON) f.Set(pdufield.SourceAddrNPI, sm.SourceAddrNPI) f.Set(pdufield.DestAddrTON, sm.DestAddrTON) f.Set(pdufield.DestAddrNPI, sm.DestAddrNPI) f.Set(pdufield.ESMClass, sm.ESMClass) f.Set(pdufield.ProtocolID, sm.ProtocolID) f.Set(pdufield.PriorityFlag, sm.PriorityFlag) f.Set(pdufield.ScheduleDeliveryTime, sm.ScheduleDeliveryTime) f.Set(pdufield.ReplaceIfPresentFlag, sm.ReplaceIfPresentFlag) f.Set(pdufield.SMDefaultMsgID, sm.SMDefaultMsgID) resp, err := t.do(p) if err != nil { return nil, err } sm.resp.Lock() sm.resp.p = resp.PDU sm.resp.Unlock() if id := resp.PDU.Header().ID; id != pdu.SubmitSMRespID { return sm, fmt.Errorf("unexpected PDU ID: %s", id) } if s := resp.PDU.Header().Status; s != 0 { return sm, s } return sm, resp.Err }