Ejemplo n.º 1
0
func encodeAndEnqueueReportingInterval(mins uint32) error {
	if downlinkMessages != nil {

		// Create a buffer that is big enough to store all
		// the encoded data and take a pointer to it's first element
		var outputBuffer [C.MAX_DATAGRAM_SIZE_RAW]byte
		outputPointer := (*C.char)(unsafe.Pointer(&outputBuffer[0]))

		// Populate the data struture to be encoded
		var data C.ReportingIntervalSetReqDlMsg_t

		//		data.reportingIntervalMinutes = C.uint32_t(mins)
		var dataPointer = (*C.ReportingIntervalSetReqDlMsg_t)(unsafe.Pointer(&data))

		// Encode the data structure into the output buffer
		cbytes := C.encodeReportingIntervalSetReqDlMsg(outputPointer, dataPointer, nil, nil)

		// Send the populated output buffer bytes to NeulNet
		payload := outputBuffer[:cbytes]
		msg := AmqpMessage{
			Device_uuid:   ueGuid,
			Endpoint_uuid: 4,
			//Payload:       payload,
		}
		for _, v := range payload {
			msg.Payload = append(msg.Payload, int(v))
			Row.TotalBytes = Row.TotalBytes + uint64(len(payload))
		}

		log.Printf("%s ENCODED A REPORTING INTERVAL UPDATE OF %d MINUTES AS %v USING AMQP MESSAGE %+v\n", logTag, mins, payload, msg)

		downlinkMessages <- msg
		now := time.Now()

		// Record the downlink data volume
		StateTableCmds <- &DataVolume{
			DownlinkTimestamp: &now,
			DownlinkBytes:     uint64(len(payload)),
		}

		return nil
	}

	return errors.New("NO DOWNLINKMESSAGES CHANNEL AVAILABLE TO ENQUEUE THE ENCODED MESSAGE")
}
Ejemplo n.º 2
0
// Encode and enqueue a message, return an error if there is one
func encodeAndEnqueue(msg interface{}, uuid string) error {

	if msg != nil {
		// Create a buffer that is big enough to store all
		// the encoded data and take a pointer to it's first element
		var outputBuffer [MaxDatagramSizeRaw]byte
		outputPointer := (*C.char)(unsafe.Pointer(&outputBuffer[0]))
		var byteCount C.uint32_t = 0
		responseId := RESPONSE_NONE

		// A place to put the XML output from the decoder
		pXmlBuffer := (*C.char)(unsafe.Pointer(&(xmlEncodeBuffer[0])))
		ppXmlBuffer := (**C.char)(unsafe.Pointer(&pXmlBuffer))
		xmlBufferLen := (C.uint32_t)(len(xmlEncodeBuffer))
		pXmlBufferLen := (*C.uint32_t)(unsafe.Pointer(&xmlBufferLen))

		// Encode each message type
		switch value := msg.(type) {
		case *TransparentDlDatagram:
			// TODO
		case *PingReqDlMsg:
			byteCount = C.encodePingReqMsg(outputPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded PingReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_PING_CNF

		case *PingCnfDlMsg:
			byteCount = C.encodePingCnfMsg(outputPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded PingCnfDlMsg.\n", globals.LogTag)

		case *RebootReqDlMsg:
			data := C.RebootReqDlMsg_t{
				sdCardNotRequired: (C.bool)(value.SdCardNotRequired),
				disableModemDebug: (C.bool)(value.DisableModemDebug),
				disableButton:     (C.bool)(value.DisableButton),
				disableServerPing: (C.bool)(value.DisableServerPing),
			}
			dataPointer := (*C.RebootReqDlMsg_t)(unsafe.Pointer(&data))
			byteCount = C.encodeRebootReqDlMsg(outputPointer, dataPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded RebootReqDlMsg.\n", globals.LogTag)

		case *DateTimeSetReqDlMsg:
			data := C.DateTimeSetReqDlMsg_t{
				time:        (C.uint32_t)(value.UtmTime.Unix()),
				setDateOnly: (C.bool)(value.SetDateOnly),
			}
			dataPointer := (*C.DateTimeSetReqDlMsg_t)(unsafe.Pointer(&data))
			byteCount = C.encodeDateTimeSetReqDlMsg(outputPointer, dataPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded DateTimeSetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_DATE_TIME_SET_CNF
		case *DateTimeGetReqDlMsg:
			byteCount = C.encodeDateTimeGetReqDlMsg(outputPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded DateTimeGetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_DATE_TIME_GET_CNF

		case *ModeSetReqDlMsg:
			data := C.ModeSetReqDlMsg_t{
				mode: (C.Mode_t)(value.Mode),
			}
			dataPointer := (*C.ModeSetReqDlMsg_t)(unsafe.Pointer(&data))
			byteCount = C.encodeModeSetReqDlMsg(outputPointer, dataPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded ModeSetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_MODE_SET_CNF

		case *ModeGetReqDlMsg:
			byteCount = C.encodeModeGetReqDlMsg(outputPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded ModeGetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_MODE_GET_CNF

		case *IntervalsGetReqDlMsg:
			byteCount = C.encodeIntervalsGetReqDlMsg(outputPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded IntervalsGetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_INTERVALS_GET_CNF

		case *ReportingIntervalSetReqDlMsg:
			data := C.ReportingIntervalSetReqDlMsg_t{
				reportingInterval: (C.uint32_t)(value.ReportingInterval),
			}
			dataPointer := (*C.ReportingIntervalSetReqDlMsg_t)(unsafe.Pointer(&data))
			byteCount = C.encodeReportingIntervalSetReqDlMsg(outputPointer, dataPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded ReportingIntervalSetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_REPORTING_INTERVAL_SET_CNF

		case *HeartbeatSetReqDlMsg:
			data := C.HeartbeatSetReqDlMsg_t{
				heartbeatSeconds:   (C.uint32_t)(value.HeartbeatSeconds),
				heartbeatSnapToRtc: (C.bool)(value.HeartbeatSnapToRtc),
			}
			dataPointer := (*C.HeartbeatSetReqDlMsg_t)(unsafe.Pointer(&data))
			byteCount = C.encodeHeartbeatSetReqDlMsg(outputPointer, dataPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded HeartbeatSetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_HEARTBEAT_SET_CNF

		case *MeasurementsGetReqDlMsg:
			byteCount = C.encodeMeasurementsGetReqDlMsg(outputPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded MeasurementsReportReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_MEASUREMENTS_GET_CNF

		// TODO
		// case *MeasurementControlSetReqDlMsg
		// case *MeasurementsControlDefaultsSetReqDlMsg

		case *TrafficReportGetReqDlMsg:
			byteCount = C.encodeTrafficReportGetReqDlMsg(outputPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded TrafficReportGetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_TRAFFIC_REPORT_GET_CNF

		case *TrafficTestModeParametersSetReqDlMsg:
			data := C.TrafficTestModeParametersSetReqDlMsg_t{
				numUlDatagrams:      (C.uint32_t)(value.NumUlDatagrams),
				lenUlDatagram:       (C.uint32_t)(value.LenUlDatagram),
				numDlDatagrams:      (C.uint32_t)(value.NumDlDatagrams),
				lenDlDatagram:       (C.uint32_t)(value.LenDlDatagram),
				timeoutSeconds:      (C.uint32_t)(value.TimeoutSeconds),
				noReportsDuringTest: (C.bool)(value.NoReportsDuringTest),
			}
			dataPointer := (*C.TrafficTestModeParametersSetReqDlMsg_t)(unsafe.Pointer(&data))
			byteCount = C.encodeTrafficTestModeParametersSetReqDlMsg(outputPointer, dataPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded TrafficTestModeParametersSetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_TRAFFIC_TEST_MODE_PARAMETERS_SET_CNF

		case *TrafficTestModeParametersGetReqDlMsg:
			byteCount = C.encodeTrafficTestModeParametersGetReqDlMsg(outputPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded TrafficTestModeParametersGetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_TRAFFIC_TEST_MODE_PARAMETERS_GET_CNF

		case *TrafficTestModeReportGetReqDlMsg:
			byteCount = C.encodeTrafficTestModeReportGetReqDlMsg(outputPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded TrafficTestModeReportGetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_TRAFFIC_TEST_MODE_REPORT_GET_CNF

		case *ActivityReportGetReqDlMsg:
			byteCount = C.encodeActivityReportGetReqDlMsg(outputPointer, ppXmlBuffer, pXmlBufferLen)
			globals.Dbg.PrintfTrace("%s [encode] --> encoded ActivityReportGetReqDlMsg.\n", globals.LogTag)
			responseId = RESPONSE_ACTIVITY_REPORT_GET_CNF

		default:
			globals.Dbg.PrintfTrace("%s [encode] --> asked to send unknown message:\n\n%s\n", globals.LogTag, spew.Sdump(msg))
		}

		if byteCount > 0 {
			totalDlMsgs++
			totalDlBytes += int(byteCount)
			lastDlMsgTime = time.Now()

			// Send the output buffer to the TSW server
			payload := outputBuffer[:byteCount]
			msg := AmqpMessage{
				DeviceUuid:   uuid,
				EndpointUuid: 4,
			}

			for _, v := range payload {
				msg.Payload = append(msg.Payload, int(v))
			}

			globals.Dbg.PrintfTrace("%s [encode] --> %d byte message for AMQP downlink:\n\n%+v\n", globals.LogTag, byteCount, msg)
			downlinkMessages <- msg
			globals.Dbg.PrintfTrace("%s [encode] --> encoded %d bytes into AMQP message:\n\n%+v\n", globals.LogTag, byteCount, msg)
			globals.Dbg.PrintfInfo("%s [encode] --> XML buffer pointer 0x%08x, used %d, left %d:.\n", globals.LogTag, *ppXmlBuffer, C.uint32_t(len(xmlEncodeBuffer))-xmlBufferLen, xmlBufferLen)

			// If a response is expected, add it to the list for this device
			if responseId != RESPONSE_NONE {
				globals.Dbg.PrintfTrace("%s [encode] --> now expecting response ID %d from UUID %s.\n", globals.LogTag, responseId, uuid)
				list := deviceExpectedMsgList[uuid]
				if list == nil {
					var expectedMsgList []ExpectedMsg
					list = &expectedMsgList
					deviceExpectedMsgList[uuid] = list
					globals.Dbg.PrintfTrace("%s [encode] --> making a new list for UUID %s, number of lists is now %d.\n", globals.LogTag, uuid, len(deviceExpectedMsgList))
				}

				expectedMsg := ExpectedMsg{
					TimeStarted: time.Now(),
					ResponseId:  responseId,
				}

				*list = append(*list, expectedMsg)
				globals.Dbg.PrintfTrace("%s [encode] --> expected list for UUID %s is now size %d.\n", globals.LogTag, uuid, len(*list))
			}

			return nil
		}

		return nil
	}

	return errors.New("No downlink message channel available to enqueue the encoded message.\n")
}