func (t *Transmitter) do(p pdu.Body) (*tx, error) { t.conn.Lock() notbound := t.conn.client == nil t.conn.Unlock() if notbound { return nil, ErrNotBound } rc := make(chan *tx, 1) seq := p.Header().Seq t.tx.Lock() t.tx.inflight[seq] = rc t.tx.Unlock() defer func() { close(rc) t.tx.Lock() delete(t.tx.inflight, seq) t.tx.Unlock() }() err := t.conn.Write(p) if err != nil { return nil, err } select { case resp := <-rc: return resp, nil case <-time.After(time.Second): return nil, errors.New("timeout waiting for response") } }
// 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) } }
func (t *Transmitter) do(p pdu.Body) (*tx, error) { t.conn.Lock() notbound := t.conn.client == nil t.conn.Unlock() if notbound { return nil, ErrNotBound } if t.conn.WindowSize > 0 { inflight := uint(atomic.AddInt32(&t.tx.count, 1)) defer func(t *Transmitter) { atomic.AddInt32(&t.tx.count, -1) }(t) if inflight > t.conn.WindowSize { return nil, ErrMaxWindowSize } } rc := make(chan *tx, 1) seq := p.Header().Seq t.tx.Lock() t.tx.inflight[seq] = rc t.tx.Unlock() defer func() { close(rc) t.tx.Lock() delete(t.tx.inflight, seq) t.tx.Unlock() }() err := t.conn.Write(p) if err != nil { return nil, err } select { case resp := <-rc: if resp.Err != nil { return nil, resp.Err } return resp, nil case <-t.conn.respTimeout(): return nil, errors.New("timeout waiting for response") } }
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) } }