func (m *AllJoynMessenger) callRemoteMethod(message *C.AJ_Message, path, member string, arguments []interface{}) (err error) {
	log.Printf("MSG: message.hdr=%p", message.hdr)
	remote := m.bus.Object(m.dbusService, dbus.ObjectPath(path))
	// log.Printf("%s Argument[0] %+v", member, reflect.ValueOf(arguments[0]).Type())
	res := remote.Call(member, 0, arguments...)

	if res.Err != nil {
		log.Printf("Error calling dbus method (%s): %s", member, res.Err)
		return res.Err
	}

	//pad := 4 - (int)(message.bodyBytes)%4
	//C.WriteBytes((*C.AJ_Message)(message), nil, (C.size_t)(0), (C.size_t)(pad))

	buf := new(bytes.Buffer)
	buf.Write(make([]byte, (int)(message.bodyBytes)))
	enc := ajmarshal.NewEncoderAtOffset(buf, (int)(message.bodyBytes), binary.LittleEndian)
	pad, err := enc.Encode(res.Body...)
	// log.Printf("Padding of the encoded buffer: %d", pad)
	if err != nil {
		log.Printf("Error encoding result: %s", err)
		return err
	}
	/*
		C.AJ_MarshalContainer((*C.AJ_Message)(message), (*C.AJ_Arg)(C.Get_Arg()), C.AJ_ARG_ARRAY)

		C.AJ_MarshalArgs_cgo((*C.AJ_Message)(message), C.CString("{sv}"), C.CString("DeviceName"), C.CString("s"), C.CString("Golang-device"))

		C.AJ_MarshalCloseContainer((*C.AJ_Message)(message), (*C.AJ_Arg)(C.Get_Arg()))
	*/
	//log.Printf("Encoded reply, len: %+v, %d", buf.Bytes(), buf.Len())
	// log.Printf("Length before: %d", message.bodyBytes)

	newBuf := buf.Bytes()[(int)(message.bodyBytes)+pad:]
	//log.Printf("Buffer to write into AllJoyn: %+v, %d", newBuf, len(newBuf))
	//	hdr := message.hdr
	//	if hdr.flags&C.uint8_t(C.AJ_FLAG_ENCRYPTED) == 0 {
	//		hdr = nil
	//	} else {
	//		message.hdr.flags &= ^C.uint8_t(C.AJ_FLAG_ENCRYPTED)
	//	}

	if len(newBuf) > 0 {
		log.Printf("MSG: message.hdr=%p", message.hdr)
		C.AJ_DeliverMsgPartial((*C.AJ_Message)(message), C.uint32_t(len(newBuf)))
		log.Printf("MSG: message.hdr=%p", message.hdr)

		C.AJ_MarshalRaw((*C.AJ_Message)(message), unsafe.Pointer(&newBuf[0]), C.size_t(len(newBuf)))
	} else {
		C.AJ_MarshalRaw((*C.AJ_Message)(message), unsafe.Pointer(&newBuf), C.size_t(0))
	}
	//log.Printf("New buff reply, len: %+v, %d", newBuf, len(newBuf))
	//	if hdr != nil {
	//		message.hdr = hdr
	//		message.hdr.flags &= ^C.uint8_t(C.AJ_FLAG_ENCRYPTED)
	//	}
	log.Printf("MSG: message.hdr=%p", message.hdr)
	return nil
}
Esempio n. 2
0
func (a *AllJoynBridge) processSignals() {

	// work on currently reveived signals only
	// TODO:https://golang.org/doc/effective_go.html#leaky_buffer
	signals := a.signals
	a.signals = make(chan *dbus.Signal, 100)
	close(signals)

	// log.Printf("Processing signals: %d", len(signals))

	for signal := range signals {
		log.Printf("**** Incoming Signal: %+v", signal)

		// get signal signature
		msgId, _ := a.findSignal(signal)

		if msgId == 0 {
			log.Printf("Could not find any matching service for signal: %+v", signal)
			continue
		}

		for _, sessionId := range a.sessions {

			var status C.AJ_Status = C.AJ_OK
			msg := C.Get_AJ_Message()

			status = C.AJ_MarshalSignal_cgo((*C.AJ_Message)(msg), C.uint32_t(msgId), C.uint32_t(sessionId), C.uint8_t(0), C.uint32_t(0))
			log.Printf("**** AJ_MarshalSignal: %d", status)

			// for _, arg := range signal.Body {
			// 	log.Printf("**** ARG: %v", arg)
			// 	signature := dbus.SignatureOf(arg).String()
			// 	sig := C.CString(signature)
			// 	defer C.free(unsafe.Pointer(sig))
			// 	status = C.MarshalArg((*C.AJ_Message)(msg), sig, unsafe.Pointer(&arg))
			// 	log.Printf("**** MarshalArg: (%s, %v) => %d", signature, arg, status)
			// }

			if len(signal.Body) > 0 {

				buf := new(bytes.Buffer)
				buf.Write(make([]byte, (int)(msg.bodyBytes)))
				enc := devicehivealljoyn.NewEncoderAtOffset(buf, (int)(msg.bodyBytes), binary.LittleEndian)
				pad, err := enc.Encode(signal.Body...)

				if err != nil {
					log.Printf("Error encoding result: %s", err)
					continue
				}

				newBuf := buf.Bytes()[(int)(msg.bodyBytes)+pad:]

				status = C.AJ_DeliverMsgPartial((*C.AJ_Message)(msg), C.uint32_t(len(newBuf)))
				log.Printf("**** AJ_DeliverMsgPartial: %d", status)

				if len(newBuf) > 0 {
					status = C.AJ_MarshalRaw((*C.AJ_Message)(msg), unsafe.Pointer(&newBuf[0]), C.size_t(len(newBuf)))
					log.Printf("**** AJ_MarshalRaw: %d", status)
				} else {
					status = C.AJ_MarshalRaw((*C.AJ_Message)(msg), unsafe.Pointer(&newBuf), C.size_t(0))
					log.Printf("**** AJ_MarshalRaw: %d", status)
				}

			}

			status = C.AJ_DeliverMsg((*C.AJ_Message)(msg))
			log.Printf("**** AJ_DeliverMsg: %d", status)

			status = C.AJ_CloseMsg((*C.AJ_Message)(msg))
			log.Printf("**** AJ_CloseMsg: %d", status)
		}

	}
}
func (a *AllJoynBridge) processSignals() {

	// work on currently reveived signals only
	// TODO:https://golang.org/doc/effective_go.html#leaky_buffer
	signals := a.signals
	a.signals = make(chan *dbus.Signal, 100)
	close(signals)

	// log.Printf("Processing signals: %d", len(signals))

	for signal := range signals {
		log.Printf("**** Incoming Signal: %+v", signal)

		if a.processNotificationSignal(signal) {
			continue
		}

		// get signal signature
		sigIntrospect, msgId := a.findSignal(signal)

		if msgId == 0 {
			log.Printf("Could not find any matching service for signal: %+v", signal)
			continue
		}
		log.Printf("%v", sigIntrospect)
		if isSessionless(sigIntrospect) {
			log.Printf("SESSIONLESS SIGNAL!")

			var status C.AJ_Status = C.AJ_OK
			msg := C.Get_AJ_Message()

			status = C.AJ_MarshalSignal_cgo(msg, C.uint32_t(msgId), C.uint32_t(0), C.AJ_FLAG_SESSIONLESS, C.uint32_t(0))
			log.Printf("**** AJ_MarshalSignal: %s", status)

			if len(signal.Body) > 0 {

				buf := new(bytes.Buffer)
				buf.Write(make([]byte, (int)(msg.bodyBytes)))
				enc := ajmarshal.NewEncoderAtOffset(buf, (int)(msg.bodyBytes), binary.LittleEndian)
				pad, err := enc.Encode(signal.Body...)

				if err != nil {
					log.Printf("Error encoding result: %s", err)
					continue
				}

				newBuf := buf.Bytes()[(int)(msg.bodyBytes)+pad:]

				if len(newBuf) > 0 {
					status = C.AJ_DeliverMsgPartial((*C.AJ_Message)(msg), C.uint32_t(len(newBuf)))
					log.Printf("**** AJ_DeliverMsgPartial: %s", status)
					status = C.AJ_MarshalRaw((*C.AJ_Message)(msg), unsafe.Pointer(&newBuf[0]), C.size_t(len(newBuf)))
				} else {
					status = C.AJ_MarshalRaw((*C.AJ_Message)(msg), unsafe.Pointer(&newBuf), C.size_t(0))
				}
				log.Printf("**** AJ_MarshalRaw: %s", status)

			}

			status = C.AJ_DeliverMsg((*C.AJ_Message)(msg))
			log.Printf("**** AJ_DeliverMsg: %s", status)

			status = C.AJ_CloseMsg((*C.AJ_Message)(msg))
			log.Printf("**** AJ_CloseMsg: %s", status)

		} else {

			for _, sessionId := range a.sessions {

				var status C.AJ_Status = C.AJ_OK
				msg := C.Get_AJ_Message()

				status = C.AJ_MarshalSignal_cgo(msg, C.uint32_t(msgId), C.uint32_t(sessionId), C.uint8_t(0), C.uint32_t(0))
				log.Printf("**** AJ_MarshalSignal: %s", status)

				if len(signal.Body) > 0 {

					buf := new(bytes.Buffer)
					buf.Write(make([]byte, (int)(msg.bodyBytes)))
					enc := ajmarshal.NewEncoderAtOffset(buf, (int)(msg.bodyBytes), binary.LittleEndian)
					pad, err := enc.Encode(signal.Body...)

					if err != nil {
						log.Printf("Error encoding result: %s", err)
						continue
					}

					newBuf := buf.Bytes()[(int)(msg.bodyBytes)+pad:]

					if len(newBuf) > 0 {
						status = C.AJ_DeliverMsgPartial((*C.AJ_Message)(msg), C.uint32_t(len(newBuf)))
						log.Printf("**** AJ_DeliverMsgPartial: %s", status)
						status = C.AJ_MarshalRaw((*C.AJ_Message)(msg), unsafe.Pointer(&newBuf[0]), C.size_t(len(newBuf)))
					} else {
						status = C.AJ_MarshalRaw((*C.AJ_Message)(msg), unsafe.Pointer(&newBuf), C.size_t(0))
					}
					log.Printf("**** AJ_MarshalRaw: %s", status)

				}

				status = C.AJ_DeliverMsg((*C.AJ_Message)(msg))
				log.Printf("**** AJ_DeliverMsg: %s", status)

				status = C.AJ_CloseMsg((*C.AJ_Message)(msg))
				log.Printf("**** AJ_CloseMsg: %s", status)
			}
		}
	}
}