func (m *AllJoynMessenger) forwardAllJoynMessage(msgId uint32) (err error) { log.Printf("****forwardAllJoynMessage****") msg := C.Get_AJ_Message() reply := C.Get_AJ_ReplyMessage() var data uintptr var actual C.size_t b := make([]byte, 0) signature := C.GoString(C.Get_AJ_Message_signature()) bodyLen := C.Get_AJ_Message_bodyLen() for i := 0; i < int(bodyLen); i++ { status := C.AJ_UnmarshalRaw((*C.AJ_Message)(msg), (*unsafe.Pointer)(unsafe.Pointer(&data)), C.size_t(1), (*C.size_t)(unsafe.Pointer(&actual))) if status == C.AJ_OK { b = append(b, C.GoBytes(unsafe.Pointer(data), C.int(actual))...) // log.Printf("Reading RAW message, status = %d, actual = %d", status, actual) } else { log.Printf("Error while reading message body, status = %d", status) break } } s, err := dbus.ParseSignature(signature) if err != nil { log.Printf("Error parsing signature: %s", err) return err } d := dbus.NewDecoder(bytes.NewReader(b), binary.LittleEndian) res, err := d.Decode(s) if err != nil { log.Printf("Error decoding message [%+v] : %s", b, err) return err } //log.Printf("Received application alljoyn message, signature: %s, bytes: %+v, decoded: %+v", signature, b, res) objPath := C.GoString(C.Get_AJ_Message_objPath()) member := C.GoString(C.Get_AJ_Message_member()) destination := C.GoString(C.Get_AJ_Message_destination()) iface := C.GoString(C.Get_AJ_Message_iface()) log.Printf("****Message [objPath, member, iface, destination]: %s, %s, %s, %s", objPath, member, iface, destination) for _, service := range m.binding { if service.allJoynPath == objPath { log.Printf("Found matching dbus service: %+v", service) C.AJ_MarshalReplyMsg((*C.AJ_Message)(msg), (*C.AJ_Message)(reply)) m.callRemoteMethod((*C.AJ_Message)(reply), service.dbusPath, iface+"."+member, res) C.AJ_DeliverMsg((*C.AJ_Message)(reply)) break } } return nil }
func (dec *decoder) decode(s string, depth int) interface{} { dec.align(alignment(typeFor(s))) switch s[0] { case 'y': var b [1]byte if _, err := dec.in.Read(b[:]); err != nil { panic(err) } dec.pos++ return b[0] case 'b': i := dec.decode("u", depth).(uint32) switch { case i == 0: return false case i == 1: return true default: panic(FormatError("invalid value for boolean")) } case 'n': var i int16 dec.binread(&i) dec.pos += 2 return i case 'i': var i int32 dec.binread(&i) dec.pos += 4 return i case 'x': var i int64 dec.binread(&i) dec.pos += 8 return i case 'q': var i uint16 dec.binread(&i) dec.pos += 2 return i case 'u': var i uint32 dec.binread(&i) dec.pos += 4 return i case 't': var i uint64 dec.binread(&i) dec.pos += 8 return i case 'd': var f float64 dec.binread(&f) dec.pos += 8 return f case 's': length := dec.decode("u", depth).(uint32) b := make([]byte, int(length)+1) if _, err := io.ReadFull(dec.in, b); err != nil { panic(err) } dec.pos += int(length) + 1 return string(b[:len(b)-1]) case 'o': return dbus.ObjectPath(dec.decode("s", depth).(string)) case 'g': length := dec.decode("y", depth).(byte) b := make([]byte, int(length)+1) if _, err := io.ReadFull(dec.in, b); err != nil { panic(err) } dec.pos += int(length) + 1 sig, err := dbus.ParseSignature(string(b[:len(b)-1])) if err != nil { panic(err) } return sig case 'v': if depth >= 64 { panic(FormatError("input exceeds container depth limit")) } var variant dbus.Variant sig := dec.decode("g", depth).(dbus.Signature) if len(sig.String()) == 0 { panic(FormatError("variant signature is empty")) } err, rem := validSingle(sig.String(), 0) if err != nil { panic(err) } if rem != "" { panic(FormatError("variant signature has multiple types")) } //variant.sig = sig //variant.value = dec.decode(sig.String(), depth+1) variant = dbus.MakeVariant(dec.decode(sig.String(), depth+1)) return variant case 'h': return dbus.UnixFDIndex(dec.decode("u", depth).(uint32)) case 'a': if len(s) > 1 && s[1] == '{' { ksig := s[2:3] vsig := s[3 : len(s)-1] v := reflect.MakeMap(reflect.MapOf(typeFor(ksig), typeFor(vsig))) if depth >= 63 { panic(FormatError("input exceeds container depth limit")) } length := dec.decode("u", depth).(uint32) // Even for empty maps, the correct padding must be included dec.align(8) spos := dec.pos for dec.pos < spos+int(length) { dec.align(8) if !isKeyType(v.Type().Key()) { panic(dbus.InvalidTypeError{v.Type()}) } kv := dec.decode(ksig, depth+2) vv := dec.decode(vsig, depth+2) v.SetMapIndex(reflect.ValueOf(kv), reflect.ValueOf(vv)) } return v.Interface() } if depth >= 64 { panic(FormatError("input exceeds container depth limit")) } length := dec.decode("u", depth).(uint32) v := reflect.MakeSlice(reflect.SliceOf(typeFor(s[1:])), 0, int(length)) // Even for empty arrays, the correct padding must be included dec.align(alignment(typeFor(s[1:]))) spos := dec.pos for dec.pos < spos+int(length) { ev := dec.decode(s[1:], depth+1) v = reflect.Append(v, reflect.ValueOf(ev)) } return v.Interface() case '(': if depth >= 64 { panic(FormatError("input exceeds container depth limit")) } dec.align(8) v := make([]interface{}, 0) s = s[1 : len(s)-1] for s != "" { err, rem := validSingle(s, 0) if err != nil { panic(err) } ev := dec.decode(s[:len(s)-len(rem)], depth+1) v = append(v, ev) s = rem } return v default: panic(dbus.SignatureError{Sig: s}) } }