Beispiel #1
0
// auth authenticate new clients.
func (srv *Server) auth(c *conn) error {
	p, err := c.Read()
	if err != nil {
		return err
	}
	var resp pdu.Body
	switch p.Header().ID {
	case pdu.BindTransmitterID:
		resp = pdu.NewBindTransmitterResp()
	case pdu.BindReceiverID:
		resp = pdu.NewBindReceiverResp()
	case pdu.BindTransceiverID:
		resp = pdu.NewBindTransceiverResp()
	default:
		return errors.New("unexpected pdu, want bind")
	}
	f := p.Fields()
	user := f[pdufield.SystemID]
	passwd := f[pdufield.Password]
	if user == nil || passwd == nil {
		return errors.New("malformed pdu, missing system_id/password")
	}
	if user.String() != srv.User {
		return errors.New("invalid user")
	}
	if passwd.String() != srv.Passwd {
		return errors.New("invalid passwd")
	}
	resp.Fields().Set(pdufield.SystemID, DefaultSystemID)
	if err = c.Write(resp); err != nil {
		return err
	}
	return nil
}
Beispiel #2
0
// Handler handles DeliverSM coming from a Transceiver SMPP connection.
// It broadcasts received delivery receipt to all registered peers.
func (pool *deliveryPool) Handler(p pdu.Body) {
	switch p.Header().ID {
	case pdu.DeliverSMID:
		f := p.Fields()
		dr := &DeliveryReceipt{
			Src:  f[pdufield.SourceAddr].String(),
			Dst:  f[pdufield.DestinationAddr].String(),
			Text: f[pdufield.ShortMessage].String(),
		}
		pool.Broadcast(dr)
	}
}
Beispiel #3
0
// bind attempts to bind the connection.
func bind(c Conn, p pdu.Body) (pdu.Body, error) {
	f := p.Fields()
	f.Set(pdufield.InterfaceVersion, 0x34)
	err := c.Write(p)
	if err != nil {
		return nil, err
	}
	resp, err := c.Read()
	if err != nil {
		return nil, err
	}
	h := resp.Header()
	if h.Status != 0 {
		return nil, h.Status
	}
	return resp, nil
}
Beispiel #4
0
func (t *Transmitter) submitMsg(sm *ShortMessage, p pdu.Body, dataCoding uint8) (*ShortMessage, error) {
	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)
	f.Set(pdufield.DataCoding, dataCoding)
	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
}
Beispiel #5
0
func pduHandler(c smpptest.Conn, p pdu.Body) {
	src := p.Fields()[pdufield.SourceAddr]
	fail := src != nil && src.String() == "root"
	switch p.Header().ID {
	case pdu.SubmitSMID:
		r := pdu.NewSubmitSMResp()
		r.Header().Seq = p.Header().Seq
		if fail {
			r.Header().Status = 0x00000045 // submitsm failed
		} else {
			r.Fields().Set(pdufield.MessageID, "foobar")
		}
		c.Write(r)
		rd := p.Fields()[pdufield.RegisteredDelivery]
		if rd == nil || rd.Bytes()[0] == 0 {
			return
		}
		r = pdu.NewDeliverSM()
		rf := r.Fields()
		pf := p.Fields()
		rf.Set(pdufield.SourceAddr, pf[pdufield.SourceAddr])
		rf.Set(pdufield.DestinationAddr, pf[pdufield.DestinationAddr])
		rf.Set(pdufield.ShortMessage, "delivery receipt here")
		c.Write(r)
	case pdu.QuerySMID:
		r := pdu.NewQuerySMResp()
		r.Header().Seq = p.Header().Seq
		if fail {
			r.Header().Status = 0x00000067 // querysm failed
		} else {
			pf := p.Fields()
			rf := r.Fields()
			rf.Set(pdufield.MessageID, pf[pdufield.MessageID])
			rf.Set(pdufield.MessageState, 2) // DELIVERED
		}
		c.Write(r)
	default:
		smpptest.EchoHandler(c, p)
	}
}
Beispiel #6
0
func (t *Transmitter) submitMsgMulti(sm *ShortMessage, p pdu.Body, dataCoding uint8) (*ShortMessage, error) {
	numberOfDest := len(sm.DstList) + len(sm.DLs) // TODO: Validate numbers and lists according to size
	if numberOfDest > MaxDestinationAddress {
		return nil, fmt.Errorf("Error: Max number of destination addresses allowed is %d, trying to send to %d",
			MaxDestinationAddress, numberOfDest)
	}
	// Put destination addresses and lists inside an byte array
	var bArray []byte
	// destination addresses
	for _, destAddr := range sm.DstList {
		// 1 - SME Address
		bArray = append(bArray, byte(0x01))
		bArray = append(bArray, byte(sm.DestAddrTON))
		bArray = append(bArray, byte(sm.DestAddrNPI))
		bArray = append(bArray, []byte(destAddr)...)
		// null terminator
		bArray = append(bArray, byte(0x00))
	}

	// distribution lists
	for _, destList := range sm.DLs {
		// 2 - Distribution List
		bArray = append(bArray, byte(0x02))
		bArray = append(bArray, []byte(destList)...)
		// null terminator
		bArray = append(bArray, byte(0x00))
	}

	f := p.Fields()
	f.Set(pdufield.SourceAddr, sm.Src)
	f.Set(pdufield.DestinationList, bArray)
	f.Set(pdufield.ShortMessage, sm.Text)
	f.Set(pdufield.NumberDests, uint8(numberOfDest))
	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.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)
	f.Set(pdufield.DataCoding, dataCoding)
	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.SubmitMultiRespID {
		return sm, fmt.Errorf("unexpected PDU ID: %s", id)
	}
	if s := resp.PDU.Header().Status; s != 0 {
		return sm, s
	}
	return sm, resp.Err
}