2024-01-22 17:35:55 +01:00
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <inttypes.h>
2024-01-24 22:08:06 +01:00
# include <math.h>
2024-01-22 17:35:55 +01:00
2024-01-24 22:08:06 +01:00
# include <mosquitto.h>
2024-01-22 17:35:55 +01:00
# include "network.h"
2024-01-22 22:00:14 +01:00
# include "mqtt.h"
# include "config.h"
2024-01-22 17:35:55 +01:00
2024-01-24 22:08:06 +01:00
# define MQTT_RREF_REQUEST_LENGTH_ID 3
# define MQTT_RREF_REQUEST_LENGTH_FREQ 3
# define MQTT_RREF_REQUEST_LENGTH_SEPARATOR 1
# define MQTT_RREF_REQUEST_SEPARATOR ' '
const int MQTT_RREF_REQUEST_START_ID = 0 ;
const int MQTT_RREF_REQUEST_START_FREQ = MQTT_RREF_REQUEST_START_ID + MQTT_RREF_REQUEST_LENGTH_ID + MQTT_RREF_REQUEST_LENGTH_SEPARATOR ;
const int MQTT_RREF_REQUEST_START_RREF = MQTT_RREF_REQUEST_START_FREQ + MQTT_RREF_REQUEST_LENGTH_FREQ + MQTT_RREF_REQUEST_LENGTH_SEPARATOR ;
const int MQTT_RREF_REQUEST_MIN_LENGTH = MQTT_RREF_REQUEST_LENGTH_ID + MQTT_RREF_REQUEST_LENGTH_FREQ + ( 2 * MQTT_RREF_REQUEST_LENGTH_SEPARATOR ) + 1 ; // at least one char for rref
int xPlaneSocket ;
struct mosquitto * mqtt ;
# define XPLANE_RREF_MAX_LENGTH 400
2024-01-22 21:20:10 +01:00
struct dref_struct_in
{
int32_t dref_freq ;
int32_t dref_sender_index ; // the index the customer is using to define this dataref
2024-01-24 22:08:06 +01:00
char dref_string [ XPLANE_RREF_MAX_LENGTH ] ;
2024-01-22 17:35:55 +01:00
} ;
2024-01-22 21:20:10 +01:00
struct dref_struct_out
{
int32_t dref_sender_index ;
float dref_flt_value ;
2024-01-22 17:35:55 +01:00
} ;
2024-01-24 22:08:06 +01:00
int * strtoint ( char * in , size_t start , size_t n )
2024-01-22 21:20:10 +01:00
{
2024-01-24 22:08:06 +01:00
int * ret = malloc ( sizeof ( int ) ) ;
* ret = 0 ;
int offset = start + n - 1 ;
2024-01-22 17:35:55 +01:00
2024-01-24 22:08:06 +01:00
if ( offset < 0 )
2024-01-22 21:20:10 +01:00
{
2024-01-24 22:08:06 +01:00
return NULL ;
}
for ( int i = 0 ; i < n ; i + + ) {
int position = offset - i ;
if ( in [ position ] > = ' 0 ' & & in [ position ] < = ' 9 ' )
{
* ret + = ( in [ position ] - ' 0 ' ) * pow ( 10 , i ) ;
}
else
{
return NULL ;
}
}
return ret ;
}
void onMessage ( struct mosquitto * mqtt , void * obj , const struct mosquitto_message * message )
{
int * id , * frequency ;
char rref [ XPLANE_RREF_MAX_LENGTH ] ;
printf ( " Received message %.*s on topic %s \n " , message - > payloadlen , ( char * ) message - > payload , message - > topic ) ;
if ( strcmp ( message - > topic , " /xplane/meta/rref " ) = = 0 )
{
printf ( " found rref request \n " ) ;
if ( message - > payloadlen > = MQTT_RREF_REQUEST_MIN_LENGTH )
{
id = strtoint ( message - > payload , MQTT_RREF_REQUEST_START_ID , MQTT_RREF_REQUEST_LENGTH_ID ) ;
frequency = strtoint ( message - > payload , MQTT_RREF_REQUEST_START_FREQ , MQTT_RREF_REQUEST_LENGTH_FREQ ) ;
if ( id = = NULL | | frequency = = NULL ) {
return ;
}
// prepare struct to send, make sure padding is with NULL bytes
struct dref_struct_in drefToRead = {
. dref_freq = * frequency ,
. dref_sender_index = * id
} ;
memset ( drefToRead . dref_string , 0 , sizeof ( drefToRead . dref_string ) ) ;
strncpy ( drefToRead . dref_string , & ( ( char * ) message - > payload ) [ MQTT_RREF_REQUEST_START_RREF ] , message - > payloadlen - MQTT_RREF_REQUEST_START_RREF ) ;
sendToXPlane ( xPlaneSocket , DEST_SERVER , DEST_PORT , " RREF " , ( char * ) & drefToRead , sizeof ( drefToRead ) ) ;
}
2024-01-22 21:20:10 +01:00
}
2024-01-24 22:08:06 +01:00
else
{
fprintf ( stderr , " Unkown topic %s \n " , message - > topic ) ;
}
}
2024-01-22 17:35:55 +01:00
2024-01-24 22:08:06 +01:00
int main ( )
{
2024-01-22 21:20:10 +01:00
// network
xPlaneSocket = createSocket ( SRC_PORT ) ;
if ( xPlaneSocket < 0 )
{
exit ( EXIT_FAILURE ) ;
}
2024-01-22 17:35:55 +01:00
2024-01-22 22:00:14 +01:00
// mqtt
2024-01-24 22:08:06 +01:00
mqtt = connectMqtt ( MQTT_USER , MQTT_PASS , onMessage ) ;
if ( mqtt = = NULL )
2024-01-22 21:20:10 +01:00
{
2024-01-24 22:08:06 +01:00
exit ( EXIT_FAILURE ) ;
2024-01-22 21:20:10 +01:00
}
2024-01-22 17:35:55 +01:00
2024-01-24 22:08:06 +01:00
// subscribe meta channel
recvMqtt ( mqtt , " /xplane/meta/# " ) ;
2024-01-22 21:20:10 +01:00
// read from network
char msg [ DGRAM_MSG_LENGTH + 1 ] ;
char payload [ RECV_BUFFER ] ;
2024-01-22 22:00:14 +01:00
char mqttTopic [ 100 ] , mqttPayload [ 512 ] ;
2024-01-22 21:20:10 +01:00
while ( 1 )
{
int payloadBytes = recvFromXPlane ( xPlaneSocket , msg , payload , RECV_BUFFER ) ;
2024-01-24 22:08:06 +01:00
if ( payloadBytes > = 0 )
2024-01-22 21:20:10 +01:00
{
if ( strcmp ( msg , " RREF " ) = = 0 )
{
2024-01-24 22:08:06 +01:00
printf ( " Received message type %s \n " , msg ) ;
printf ( " Received message data (%d) " , payloadBytes ) ;
for ( int i = 0 ; i < payloadBytes ; i + + )
{
printf ( " %02x " , payload [ i ] ) ;
}
printf ( " \n " ) ;
2024-01-24 22:29:48 +01:00
// continue if payloadBytes is valid (1 byte + 8 bytes each dref)
if ( ( payloadBytes - 1 ) % sizeof ( struct dref_struct_out ) = = 0 )
2024-01-22 21:20:10 +01:00
{
2024-01-24 22:29:48 +01:00
// loop throught all provided drefs
for ( int i = 1 ; i < payloadBytes ; i + = sizeof ( struct dref_struct_out ) )
{
memset ( mqttTopic , 0 , sizeof ( mqttTopic ) ) ;
memset ( mqttPayload , 0 , sizeof ( mqttPayload ) ) ;
2024-01-22 22:00:14 +01:00
2024-01-24 22:29:48 +01:00
struct dref_struct_out drefRead ;
memcpy ( & drefRead , & payload [ i ] , sizeof ( struct dref_struct_out ) ) ;
2024-01-22 17:35:55 +01:00
2024-01-24 22:29:48 +01:00
printf ( " %d: %f \n " , drefRead . dref_sender_index , drefRead . dref_flt_value ) ;
2024-01-22 22:00:14 +01:00
2024-01-24 22:29:48 +01:00
sprintf ( mqttTopic , " /xplane/rref/%d " , drefRead . dref_sender_index ) ;
sprintf ( mqttPayload , " %f " , drefRead . dref_flt_value ) ;
2024-01-22 22:00:14 +01:00
2024-01-24 22:29:48 +01:00
sendMqtt ( mqtt , mqttTopic , mqttPayload , strlen ( mqttPayload ) ) ;
}
2024-01-22 21:20:10 +01:00
}
else
{
exit ( EXIT_FAILURE ) ;
}
}
else
{
// unknown to me
}
}
else
{
exit ( EXIT_FAILURE ) ;
}
2024-01-24 22:08:06 +01:00
mosquitto_loop ( mqtt , 100 , 1 ) ;
2024-01-22 21:20:10 +01:00
}
2024-01-22 17:35:55 +01:00
2024-01-22 21:20:10 +01:00
// bye bye (and no, I don't care about error anymore; I'll exit anyway?!)
2024-01-22 22:00:14 +01:00
disconnectMqtt ( mqtt ) ;
2024-01-22 21:20:10 +01:00
closeSocket ( xPlaneSocket ) ;
exit ( EXIT_SUCCESS ) ;
2024-01-22 17:35:55 +01:00
}