nmxact/nmp/nmp.go (111 lines of code) (raw):

/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package nmp import ( "encoding/binary" "encoding/hex" "fmt" log "github.com/sirupsen/logrus" "github.com/ugorji/go/codec" "mynewt.apache.org/newtmgr/nmxact/nmxutil" ) const NMP_HDR_SIZE = 8 type NmpHdr struct { Op uint8 /* 3 bits of opcode */ Flags uint8 Len uint16 Group uint16 Seq uint8 Id uint8 } type NmpMsg struct { Hdr NmpHdr Body interface{} } // Combine req + rsp. type NmpReq interface { Hdr() *NmpHdr SetHdr(hdr *NmpHdr) Msg() *NmpMsg } type NmpRsp interface { Hdr() *NmpHdr SetHdr(msg *NmpHdr) Msg() *NmpMsg } type NmpBase struct { hdr NmpHdr `codec:"-"` } func (b *NmpBase) Hdr() *NmpHdr { return &b.hdr } func (b *NmpBase) SetHdr(h *NmpHdr) { b.hdr = *h } func MsgFromReq(r NmpReq) *NmpMsg { return &NmpMsg{ *r.Hdr(), r, } } func NewNmpMsg() *NmpMsg { return &NmpMsg{} } func DecodeNmpHdr(data []byte) (*NmpHdr, error) { if len(data) < NMP_HDR_SIZE { return nil, fmt.Errorf( "Newtmgr request buffer too small %d bytes", len(data)) } hdr := &NmpHdr{} hdr.Op = uint8(data[0]) hdr.Flags = uint8(data[1]) hdr.Len = binary.BigEndian.Uint16(data[2:4]) hdr.Group = binary.BigEndian.Uint16(data[4:6]) hdr.Seq = uint8(data[6]) hdr.Id = uint8(data[7]) return hdr, nil } func (hdr *NmpHdr) Bytes() []byte { buf := make([]byte, 0, NMP_HDR_SIZE) buf = append(buf, byte(hdr.Op)) buf = append(buf, byte(hdr.Flags)) u16b := make([]byte, 2) binary.BigEndian.PutUint16(u16b, hdr.Len) buf = append(buf, u16b...) binary.BigEndian.PutUint16(u16b, hdr.Group) buf = append(buf, u16b...) buf = append(buf, byte(hdr.Seq)) buf = append(buf, byte(hdr.Id)) return buf } func BodyBytes(body interface{}) ([]byte, error) { data := make([]byte, 0) enc := codec.NewEncoderBytes(&data, new(codec.CborHandle)) if err := enc.Encode(body); err != nil { return nil, fmt.Errorf("Failed to encode message %s", err.Error()) } log.Debugf("Encoded %+v to:\n%s", body, hex.Dump(data)) return data, nil } func EncodeNmpPlain(nmr *NmpMsg) ([]byte, error) { bb, err := BodyBytes(nmr.Body) if err != nil { return nil, err } nmr.Hdr.Len = uint16(len(bb)) hb := nmr.Hdr.Bytes() data := append(hb, bb...) log.Debugf("Encoded:\n%s", hex.Dump(data)) return data, nil } func fillNmpReqWithSeq(req NmpReq, op uint8, group uint16, id uint8, seq uint8) { hdr := NmpHdr{ Op: op, Flags: 0, Len: 0, Group: group, Seq: seq, Id: id, } req.SetHdr(&hdr) } func fillNmpReq(req NmpReq, op uint8, group uint16, id uint8) { fillNmpReqWithSeq(req, op, group, id, nmxutil.NextNmpSeq()) }