diff --git a/packages/ipp/collection.go b/packages/ipp/collection.go new file mode 100644 index 0000000..5a44282 --- /dev/null +++ b/packages/ipp/collection.go @@ -0,0 +1,74 @@ +package ipp + +import ( + "bufio" + "encoding/binary" + + log "github.com/sirupsen/logrus" +) + +// Currently the collection data is just consumed and dropped from the bytestream +func consumeCollection(byteStream *bufio.Reader) { + // RFC8010 Section 3.1.6 + var length uint16 + + binary.Read(byteStream, binary.BigEndian, &length) + collectionName := make([]byte, length) + if length > 0 { + binary.Read(byteStream, binary.BigEndian, collectionName) + } + log.Info("collection name " + string(collectionName)) + err := binary.Read(byteStream, binary.BigEndian, &length) //Always zero ?? + if err != nil { + log.Fatal("error ", err.Error()) + } + if length != 0 { + log.Fatal("Should be zero") + } + // Member attributes +done: + for { + var t tag + binary.Read(byteStream, binary.BigEndian, &t) + log.Debug("Collection tag ", t) + switch t { + case endCollectionValueTag: + binary.Read(byteStream, binary.BigEndian, &length) + if length != 0 { + log.Fatal("Should be zero") + } + binary.Read(byteStream, binary.BigEndian, &length) + if length != 0 { + log.Fatal("Should be zero") + } + case memberAttrNameValueTag: + // RFC8010 Section 3.7.1 + binary.Read(byteStream, binary.BigEndian, &length) //Always zero ?? + if length != 0 { + log.Fatal("Should be zero") + } + binary.Read(byteStream, binary.BigEndian, &length) // Value length + memberName := make([]byte, length) + binary.Read(byteStream, binary.BigEndian, memberName) + log.Debugf("Member name: %v", string(memberName)) + var memberValueTag tag + binary.Read(byteStream, binary.BigEndian, &memberValueTag) + log.Debug("Member value tag: ", memberValueTag) + binary.Read(byteStream, binary.BigEndian, &length) //Always zero ?? + if length != 0 { + log.Fatal("Should be zero") + } + var memberValueLength uint16 + binary.Read(byteStream, binary.BigEndian, &memberValueLength) + memberValue := make([]byte, memberValueLength) + binary.Read(byteStream, binary.BigEndian, memberValue) + log.Debugf("Member Value: % x", memberValue) + default: + // Next tag is one that can not be handled in the collection + // Put it back in the byte stream and return to main loop + byteStream.UnreadByte() + break done + } + } + log.Debug("Collection done") +} diff --git a/packages/ipp/messages.go b/packages/ipp/messages.go index 49ff1c5..f34add6 100644 --- a/packages/ipp/messages.go +++ b/packages/ipp/messages.go @@ -2,6 +2,7 @@ package ipp import ( + "bufio" "encoding/binary" "fmt" "io" @@ -81,6 +82,7 @@ const ( type printerState int32 +// printerstate defenitions const ( Idle printerState = 3 Processing printerState = 4 @@ -89,6 +91,7 @@ const ( type statusCode uint16 +// status code defenitions const ( SuccessfulOk statusCode = 0x0000 ClientErrorBadRequest statusCode = 0x0400 @@ -180,11 +183,11 @@ func (a *attributes) addAttribute(group tag, attr Attribute) { } } -func UnMarshalAttributues(body io.Reader) *attributes { +func UnMarshalAttributes(bytestream *bufio.Reader) *attributes { a := new(attributes) var t tag - err := binary.Read(body, binary.BigEndian, &t) + err := binary.Read(bytestream, binary.BigEndian, &t) if err != nil { log.Error(err.Error()) } @@ -197,9 +200,9 @@ func UnMarshalAttributues(body io.Reader) *attributes { var lastAddValuer AddValuer for { - err = binary.Read(body, binary.BigEndian, &t) + err = binary.Read(bytestream, binary.BigEndian, &t) if err != nil { - log.Errorf("End of input before end of attributes tag (%v)", err.Error()) + log.Fatal("End of input before end of attributes tag (%v)", err.Error()) } log.Debugf("Value tag - %v", t) switch t { @@ -207,21 +210,25 @@ func UnMarshalAttributues(body io.Reader) *attributes { return a case charsetValueTag: c := NewCharSetValue("", "") - c.unmarshal(body) + c.unmarshal(bytestream) a.addAttribute(currentAttributeGroup, c) log.Debugf("%v %v", c.name, c.value) + case booleanValueTag: + na := NewBoolean("", false) + na.unmarshal(bytestream) + a.addAttribute(currentAttributeGroup, na) case uriValueTag: u := NewURIValue("", "") - u.unmarshal(body) + u.unmarshal(bytestream) a.addAttribute(currentAttributeGroup, u) log.Debugf("%v %v", u.name, u.value) case naturalLanguageValueTag: n := NewNaturalLanguage("", "") - n.unmarshal(body) + n.unmarshal(bytestream) a.addAttribute(currentAttributeGroup, n) log.Debugf("%v %v", n.name, n.value) case keyWordValueTag: - name, value := unmarshalSingleValue(body) + name, value := unmarshalSingleValue(bytestream) if name == "" { lastAddValuer.addValue(value) } else { @@ -232,11 +239,16 @@ func UnMarshalAttributues(body io.Reader) *attributes { log.Debugf("%v : %v", name, value) case nameWithoutLanguageValueTag: n := NewNameWithoutLanguage("", "") - n.unmarshal(body) + n.unmarshal(bytestream) a.addAttribute(currentAttributeGroup, n) log.Debugf("%v %v", n.name, n.value) + case textWithoutLanguageValueTag: + attr := NewtextWithoutLanguage("", "") + attr.unmarshal(bytestream) + a.addAttribute(currentAttributeGroup, attr) + log.Debugf("%v %v", attr.name, attr.value) case mimeMediaTypeValueTag: - name, value := unmarshalSingleValue(body) + name, value := unmarshalSingleValue(bytestream) if name == "" { lastAddValuer.addValue(value) } else { @@ -246,7 +258,7 @@ func UnMarshalAttributues(body io.Reader) *attributes { } log.Debugf("%v : %v", name, value) case integerValueTag: - name, value := unmarshalSingleInteger(body) + name, value := unmarshalSingleInteger(bytestream) if name == "" { lastAddValuer.addValue(value) } else { @@ -256,7 +268,7 @@ func UnMarshalAttributues(body io.Reader) *attributes { } log.Debugf("%v : %v", name, value) case rangeOfIntegerValueTag: - name, value := unmarshalSingleRangeOfInteger(body) + name, value := unmarshalSingleRangeOfInteger(bytestream) if name == "" { lastAddValuer.addValue(value) } else { @@ -266,7 +278,7 @@ func UnMarshalAttributues(body io.Reader) *attributes { } log.Debugf("%v : %v", name, value) case enumValueTag: - name, value := unmarshalSingleInteger(body) + name, value := unmarshalSingleInteger(bytestream) if name == "" { lastAddValuer.addValue(value) } else { @@ -275,6 +287,9 @@ func UnMarshalAttributues(body io.Reader) *attributes { lastAddValuer = e } log.Debugf("%v : %v", name, value) + case begCollectionValueTag: + // For now just consume the collection + consumeCollection(bytestream) case jobAttributes: log.Debug("Start job attributes") currentAttributeGroup = jobAttributes @@ -286,11 +301,11 @@ func UnMarshalAttributues(body io.Reader) *attributes { currentAttributeGroup = operationAttributes case resolutionValueTag: res := NewResolution("", 0, 0) - res.unmarshal(body) + res.unmarshal(bytestream) a.addAttribute(currentAttributeGroup, res) log.Debugf("Resolution %v", res) default: - log.Errorf("Unsupported tag %v", t) + log.Errorf("Unsupported tag %v (%x)", t, uint8(t)) } } } diff --git a/packages/ipp/request.go b/packages/ipp/request.go index ba039a3..70dc15a 100644 --- a/packages/ipp/request.go +++ b/packages/ipp/request.go @@ -1,6 +1,7 @@ package ipp import ( + "bufio" "bytes" "encoding/binary" "fmt" @@ -55,9 +56,10 @@ func (r Request) String() string { } func (r *Request) UnMarshal(body io.Reader) { - r.header.unmarshal(body) + buffbody := bufio.NewReader(body) + r.header.unmarshal(buffbody) //log.Printf("Header %v", r.header) - r.a = UnMarshalAttributues(body) + r.a = UnMarshalAttributes(buffbody) } func (r *Request) RequestID() uint32 { diff --git a/packages/ipp/response.go b/packages/ipp/response.go index 786bb5c..6f0befe 100644 --- a/packages/ipp/response.go +++ b/packages/ipp/response.go @@ -1,6 +1,7 @@ package ipp import ( + "bufio" "encoding/binary" "fmt" "io" @@ -75,9 +76,10 @@ func (r *Response) Marshal() []byte { } func (r *Response) UnMarshal(body io.Reader) { - r.header.unmarshal(body) + buffbody := bufio.NewReader(body) + r.header.unmarshal(buffbody) //log.Printf("Header %v", r.header) - r.a = UnMarshalAttributues(body) + r.a = UnMarshalAttributes(buffbody) } func (r *Response) AddPrinterAttribute(a Attribute) { diff --git a/packages/ipp/textWithoutLanguage.go b/packages/ipp/textwithoutlanguage.go similarity index 100% rename from packages/ipp/textWithoutLanguage.go rename to packages/ipp/textwithoutlanguage.go