float	myFlightLoopCallback(float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void * inRefcon)
{
    if(gPluginEnabled && gnsOpened)
    {
#if 0 //FIXME
        if(autopilotConnected)
        {
            XPLMSetDatai(g_override_autopilot_ref, 1);
            XPLMSetDatai(g_autopilot_state_ref, 512); //see doc (HNAV engaged)

            override_gps = 1;//;pIntf->override_gps;
            XPLMSetDatai(g_override_gps_ref, override_gps);

            gps_fromto = 1;
            XPLMSetDatai(g_gps_fromto_ref, gps_fromto);

            gps_course_degtm = pIntf->dtk;
            XPLMSetDataf(g_gps_course_degtm_ref, gps_course_degtm);

            hsi_obs_deg_mag_pilot = pIntf->dtk;
            XPLMSetDataf(g_hsi_obs_deg_mag_pilot_ref, hsi_obs_deg_mag_pilot);


            XPLMSetDataf(g_gps_hdef_dot_ref, pIntf->cdi_horizontal_offtrack);

        } else
        {
            XPLMSetDatai(g_override_autopilot_ref, 0);
        }
#endif

        //Set the COM frequencies
        XPLMSetDatai(g_com1_active_ref, gGNSx30Proxy.getCOMActiveFrequency()/10);
        XPLMSetDatai(g_com1_standby_ref, gGNSx30Proxy.getCOMStandbyFrequency()/10);

        XPLMSetDatai(g_nav1_active_ref, gGNSx30Proxy.getNAVActiveFrequency()/10);
        XPLMSetDatai(g_nav1_standby_ref, gGNSx30Proxy.getNAVStandbyFrequency()/10);

        latitude = XPLMGetDatad(g_latitude_ref);
        longitude = XPLMGetDatad(g_longitude_ref);
        heading = XPLMGetDataf(g_heading_ref);
        groundspeed = XPLMGetDataf(g_groundspeed_ref);
        elevation = (float)XPLMGetDatad(g_elevation_ref);
        vert_speed = XPLMGetDataf(g_vert_speed_ref);

        if(heading > 180.0f) // from 0 t pi and from -pi to 0
            heading = -360.0f + heading;


        gGNSx30Proxy.setGPSInfo(latitude * PI / 180.0f, // rad
                                longitude * PI / 180.0f, // rad
                                groundspeed,
                                heading*PI/180.0f,
                                vert_speed,
                                elevation);

    }

    return gUpdateInterval; //update every 0.01 sec
}
Example #2
0
float sendRequestedDataCallback(
                                   float	inElapsedSinceLastCall,
                                   float	inElapsedTimeSinceLastFlightLoop,
                                   int		inCounter,
                                   void *	inRefcon) {

	int i;
	int res;
#if IBM
	char msg[80];
#endif
	struct RequestRecord rr;

	if( DEBUG ) {
		XPLMDebugString("XData: sendRequestedDataCallback called.\n");
	}

	if (xdata_plugin_enabled && xdata_send_enabled && xdata_socket_open) {
	
		if( acf_packet_requested == 1 ) {			
			acf_packet_requested = 0;
			sendAircraftPacket();
		}
	
		// Tried a number of things, but absolute current time in millis just overflows and isn't printable via sprintf, it seems, as a long long.
		// So: initializing a start time, then evaluating time since that, which fits into an int.
		if( t_start.time == 0 ) {
			ftime(&t_start);
			XPLMDebugString("Initialising t_start.\n");
		}


		struct timeb t_current;
		ftime(&t_current);
		int t_diff = (int) (1000.0 * (t_current.time - t_start.time) + (t_current.millitm - t_start.millitm));
		
		// clear the buffer
		memset(response_data, 0, response_max_size);
		
//		sprintf(msg, "Time check: milliseconds since start = %d\n", t_diff);
//		XPLMDebugString(msg);
				
		strncpy(response_data, "REQD", 4);		// first 4 bytes indicate packet type
		response_index = 8;
		number_of_points = 0;
		
		// work out which requests to send
		for( i=0; i<=max_requested_index; i++ ) {
			rr = request_records[i];
			if( rr.enabled && request_records[i].dataref != NULL ) {
				//sprintf(msg, "%d - Checking %s which is scheduled for %d\n", t_diff, rr.dataref_name, rr.time_next_send);
				//XPLMDebugString(msg);
				if( rr.time_next_send == 0 || t_diff > rr.time_next_send ) {
					
					// let's work out the size of the data
					int size = 0;
					
					int nbrArrayValues = 0;
					
					int intValue = 0;
					float floatValue = 0.0f;
					double doubleValue = 0.0;
					int intArrayValues[20];
					float floatArrayValues[20];
					char data[900];
					
					if( request_records[i].datatype == xplmType_Int ) {
						intValue = XPLMGetDatai(request_records[i].dataref);
						size = 4;
					} else
					if( request_records[i].datatype == xplmType_Float ) {
						floatValue = XPLMGetDataf(request_records[i].dataref);
						size = 4;
					} else
					if( request_records[i].datatype == xplmType_Double || request_records[i].datatype == 6 ) {  // hack based on observed values
						doubleValue = XPLMGetDatad(request_records[i].dataref);
						size = 8;
					} else			
					if( request_records[i].datatype == xplmType_FloatArray ) {
						nbrArrayValues = XPLMGetDatavf(request_records[i].dataref, floatArrayValues, 0, 20);
						size = (4 * nbrArrayValues);
					} else
					if( request_records[i].datatype == xplmType_IntArray ) {
						nbrArrayValues = XPLMGetDatavi(request_records[i].dataref, intArrayValues, 0, 20);
						size = (4 * nbrArrayValues);
					} else
					if( request_records[i].datatype == xplmType_Data ) {
						nbrArrayValues = XPLMGetDatab(request_records[i].dataref, data, 0, 900);
						size = nbrArrayValues;
					}
				
					
					// will it fit in the buffer
					int index_after_add = response_index + 4 + 4 + 4 + size;
					if( index_after_add >= response_max_size ) {
						// if not, send it
						// first update response with number of points
						int convertedNum = custom_htonl(number_of_points);
						memcpy(response_data+4, &convertedNum, 4);
						
						if( DEBUG ) {
							sprintf(msg, "Packet ready to go: number_of_points=%d response_index=%d\n", number_of_points, response_index);
							XPLMDebugString(msg);
							XPLMDebugString("Packet data: ");
							int p=0;
							for( p=0; p<response_index; p++ ) {
								sprintf(msg, "%d:%d ", p, (int)response_data[p]);
								XPLMDebugString(msg);
							}
							XPLMDebugString("\n");
						}
						
						// ready to go	
						for (i=0; i<NUM_DEST; i++) {
							if (dest_enable[i]) {
								res = sendto(sockfd, response_data, response_index, 0, (struct sockaddr *)&dest_sockaddr[i], sizeof(struct sockaddr));
				#if IBM
								if ( res == SOCKET_ERROR ) {
									XPLMDebugString("XData: caught error while sending REQD packet! (");
									sprintf(msg, "%d", WSAGetLastError());
									XPLMDebugString(msg);
									XPLMDebugString(")\n");
								}
				#else
								if ( res < 0 ) {
									XPLMDebugString("XData: caught error while sending REQD packet! (");
									XPLMDebugString((char * const) strerror(GET_ERRNO));
									XPLMDebugString(")\n");
								}
				#endif
							}
						}
						
						XPLMDebugString("Sent packet\n");						
						response_index = 8;
						number_of_points = 0;
						
					} else {			
						// otherwise add it to the buffer
						
						// TODO figure out how to either convert each of the above datatypes into char[] data, or
						// simply memcpy from the original dataref into the buffer.
						
						// ID|DATATYPE|LENGTH|DATA....
						int convertedI = custom_htonl(i);
						memcpy(response_data+response_index, &convertedI, 4);
						response_index += 4;
						
						int convertedDatatype = custom_htonl(request_records[i].datatype);
						memcpy(response_data+response_index, &convertedDatatype, 4);
						response_index += 4;
						
						int convertedSize = custom_htonl(size);
						memcpy(response_data+response_index, &convertedSize, 4);
						response_index += 4;

						if( request_records[i].datatype == xplmType_Int ) {
							int convertedInt = custom_htonl(intValue);
							memcpy(response_data+response_index, &convertedInt, 4);
							response_index += 4;
						} else
						if( request_records[i].datatype == xplmType_Float ) {
							// skipping endianness conversion of float too, similar problem to double?
							//float convertedFloat = custom_htonf(floatValue);
							memcpy(response_data+response_index, &floatValue, 4);
							response_index += 4;
							if( DEBUG ) {
								sprintf(msg, "Converted a float: %f\n", floatValue);
								XPLMDebugString(msg);
								sprintf(msg, "%d %d %d %d\n", (int)response_data[response_index-4], (int)response_data[response_index-3], (int)response_data[response_index-2], (int)response_data[response_index-1]);
								XPLMDebugString(msg);								
							}							
						} else
						if( request_records[i].datatype == xplmType_Double || request_records[i].datatype == 6 ) {  // hack based on observed values
						
							// Now this is weird.  Converting the double breaks it somehow.  Even reversing the byte order at the receiving
							// end doesn't work..
							//double convertedDouble = custom_htond(doubleValue);
							memcpy(response_data+response_index, &doubleValue, 8);
							response_index += 8;
						} else			
						if( request_records[i].datatype == xplmType_FloatArray ) {
							int d = 0;
							for( d = 0; d<nbrArrayValues; d++ ) {
								float convertedFloat = custom_htonf(floatArrayValues[d]);
								memcpy(response_data+response_index, &convertedFloat, 4);
								response_index += 4;
							}
						} else
						if( request_records[i].datatype == xplmType_IntArray ) {
							int d = 0;
							for( d = 0; d<nbrArrayValues; d++ ) {
								int convertedInt = custom_htonl(intArrayValues[d]);
								memcpy(response_data+response_index, &convertedInt, 4);
								response_index += 4;
							}
						} else
						if( request_records[i].datatype == xplmType_Data ) {
							memcpy(response_data+response_index, &data, size);
							response_index += size;
						}
						
						
						
						
						
						response_index = index_after_add;
						number_of_points++;	
						
						if( DEBUG ) {
							sprintf(msg, "Packet accumulating: number_of_points=%d response_index=%d\n", number_of_points, response_index);
							XPLMDebugString(msg);						
						}
						
					}

					// schedule next time
					request_records[i].time_next_send = t_diff + rr.every_millis;
//					sprintf(msg, "%d - Would send %s and rescheduled (every %d millis) for %d\n", t_diff, rr.dataref_name, rr.every_millis, rr.time_next_send);
//					XPLMDebugString(msg);
				}
			}
		}
		
		// does the buffer contain any data?
		if( number_of_points > 0 ) {
			// send it
			
			// first update response with number of points
			int convertedNum = custom_htonl(number_of_points);
			memcpy(response_data+4, &convertedNum, 4);
			
			if( DEBUG ) {
				sprintf(msg, "Packet ready to go: number_of_points=%d response_index=%d\n", number_of_points, response_index);
				XPLMDebugString(msg);
				XPLMDebugString("Packet data: ");
				int p=0;
				for( p=0; p<response_index; p++ ) {
					sprintf(msg, "%d:%d ", p, (int)response_data[p]);
					XPLMDebugString(msg);
				}
				XPLMDebugString("\n");
			}
			
			// ready to go		
			for (i=0; i<NUM_DEST; i++) {
				if (dest_enable[i]) {
					res = sendto(sockfd, response_data, response_index, 0, (struct sockaddr *)&dest_sockaddr[i], sizeof(struct sockaddr));
	#if IBM
					if ( res == SOCKET_ERROR ) {
						XPLMDebugString("XData: caught error while sending REQD packet! (");
						sprintf(msg, "%d", WSAGetLastError());
						XPLMDebugString(msg);
						XPLMDebugString(")\n");
					}
	#else
					if ( res < 0 ) {
						XPLMDebugString("XData: caught error while sending REQD packet! (");
						XPLMDebugString((char * const) strerror(GET_ERRNO));
						XPLMDebugString(")\n");
					}
	#endif
				}
			}
			
			if( DEBUG ) {
				XPLMDebugString("Sent packet.\n");				
			}
		}
		
/*
	long		time_last_sent;
	long 		every_millis;
	long		time_next_send;
	
	
every 100 ms, create a buffer (well, reuse it for performance) and start populating it with eligible data.  Keep going until the next ref would overflow the buffer.
 send the packet, then resume from the current ref.  until there are no more eligible refs.  send that last packet, if there's something in it.
 upon adding the data to the packet, update the struct with the calculated next send time.
 
REQD|COUNT|ID|DATATYPE|LENGTH|DATA.....................................|(repeated ID, TYPE, LEN, DATA)..

	
*/	
	
/*
		packet_size = createSituationPacket();

		for (i=0; i<NUM_DEST; i++) {
			if (dest_enable[i]) {
				res = sendto(sockfd, (const char*)&sim_packet, packet_size, 0, (struct sockaddr *)&dest_sockaddr[i], sizeof(struct sockaddr));
#if IBM
				if ( res == SOCKET_ERROR ) {
					XPLMDebugString("XData: caught error while sending REQD packet! (");
                    sprintf(msg, "%d", WSAGetLastError());
					XPLMDebugString(msg);
					XPLMDebugString(")\n");
				}
#else
				if ( res < 0 ) {
					XPLMDebugString("XData: caught error while sending REQD packet! (");
					XPLMDebugString((char * const) strerror(GET_ERRNO));
					XPLMDebugString(")\n");
				}
#endif
			}
		}
*/
		return 0.1;

	} else {

		// print something to allow us to work out what happened.
		XPLMDebugString("XData: plugin enabled:");
		if( xdata_plugin_enabled ) {
			XPLMDebugString("true\n");
		} else {
			XPLMDebugString("false\n");
		}

		XPLMDebugString("XData: send enabled:");
		if( xdata_send_enabled ) {
			XPLMDebugString("true\n");
		} else {
			XPLMDebugString("false\n");
		}

		XPLMDebugString("XData: socket open:");
		if( xdata_socket_open ) {
			XPLMDebugString("true\n");
		} else {
			XPLMDebugString("false\n");
		}
	
		return 0.1f;
	}

}