/******************** (C) COPYRIGHT 2020 Geek************************************
* File Name          : pdr_parseData.c
* Department         : Sensor Algorithm Team
* Current Version    : V1.0
* Author             : 
* Date of Issued     : 2021.01.29
* Comments           : GNSS数据解析，解析来自上层传入算法的字符串数据。主要是两种类
					   型。IMU字符串和NMEA字符串。
					   IMU格式 : time_ms, type, data_x, data_y, data_z
					   GPS格式 ：time_ms, type, utc_time(second unit), $GPXXX,...
					   其中time_ms是时间戳单位，时间单位要求是ms，不是ms需要转换为ms
					   type是传感器类型码，代表传入字符串所代表的传感器类型。
					   NMEA协议一般是$G开头。NMEA协议一般会附带utc时间，单位是秒(s)
********************************************************************************/
/* Header File Including -----------------------------------------------------*/
#include <stdio.h>
#include <math.h> 
#include <malloc.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdbool.h>
#include "parseData.h"
#include "PDRSensor.h"
#include "Interface.h"

extern Sensor_t SensorDataHist[IMU_LAST_COUNT];


char * strtok_ct(char * s, const char * delim)
{
	static char* lasts;
	if (s == 0)s = lasts;
	if (*s == '\0')return 0;
	lasts = s + strcspn(s, delim);
	if (*lasts != 0)*lasts++ = 0;
	return s;
}

/**----------------------------------------------------------------------
* Function    : Int2Hex
* Description : 十六进制数转换为十进制数
* Date        : 2020/7/9 yuanlin@vivo.com & logzhan
*---------------------------------------------------------------------**/
char* Int2Hex(int a, char *buffer)
{
	sprintf(buffer, "%X", a);
	return (buffer);
}

/**----------------------------------------------------------------------
* Function    : HexToDec
* Description : 十六进制数转换为十进制数
* Date        : 2022-09-15 logzhan
*---------------------------------------------------------------------**/
long HexToDec(char *source)
{
	long sum = 0, t = 1;
	int len = (int)strlen(source);
	for (int i = len - 1; i >= 0; i--) {
		sum += t * pdr_getIndexOfSigns(*(source + i));
		t *= 16;
	}
	return sum;
}

/**----------------------------------------------------------------------
* Function    : pdr_getIndexOfSigns
* Description : 返回ch字符在sign数组中的序号
* Date        : 2020/7/9 yuanlin@vivo.com &logzhan
*---------------------------------------------------------------------**/
int pdr_getIndexOfSigns(char ch)
{
	if (ch >= '0' && ch <= '9')return ch - '0';
	if (ch >= 'A' && ch <= 'F')return ch - 'A' + 10;
	if (ch >= 'a' && ch <= 'f')return ch - 'a' + 10;
	return -1;
}

void ParseIMU(char* pt, IMU_t *imu_p, double ts, int sstp)
{
	int i = 0;
	int j = 0;
	Sensor_t data_xyz = { 0 };
	Sensor_t outputData = { 0 };
	data_xyz.update = 1;
	while (pt && 3 > i)
	{
		if (0 == i)
		{
			data_xyz.s[0] = (float)atof(pt);
		}
		else if (1 == i)
		{
			data_xyz.s[1] = (float)atof(pt);
		}
		else if (2 == i)
		{
			data_xyz.s[2] = (float)atof(pt);
		}
		data_xyz.time = ts;

		pt = strtok_ct(NULL, ",");
		i++;
	}

#if 0
	if (SENSOR_ACC == sstp)
	{
		memcpy(&imu_p->acc, &data_xyz, sizeof(sensor_agm));
	}
	else if (SENSOR_MAG == sstp)
	{
		memcpy(&imu_p->mag, &data_xyz, sizeof(sensor_agm));
	}
	else if (SENSOR_GYRO == sstp)
	{
		memcpy(&imu_p->gyro, &data_xyz, sizeof(sensor_agm));
	}
#else
	data_xyz.type = sstp;
	//Hist_SensorData第0位为时间上最靠前的数据
	if (SensorDataHist[0].time > data_xyz.time)
	{
		memcpy(&outputData, &data_xyz, sizeof(Sensor_t));
	}
	else
	{
		memcpy(&outputData, &SensorDataHist[0], sizeof(Sensor_t));

		for (i = IMU_LAST_COUNT - 1; i >= 0; i--)
		{
			if ((SensorDataHist[i].time <= data_xyz.time))
			{
				for (j = 1; j <= i ; j++)
				{
					memcpy(&SensorDataHist[j - 1], &SensorDataHist[j], sizeof(Sensor_t));
				}
				memcpy(&SensorDataHist[i], &data_xyz, sizeof(Sensor_t));
				break;
			}
		}
	}

	if (SENSOR_ACC == outputData.type)
	{
		memcpy(&imu_p->acc, &outputData, sizeof(Sensor_t));
	}
	else if (SENSOR_MAG == outputData.type)
	{
		memcpy(&imu_p->mag, &outputData, sizeof(Sensor_t));
	}
	else if (SENSOR_GYRO == outputData.type)
	{
		memcpy(&imu_p->gyr, &outputData, sizeof(Sensor_t));
	}

#endif
}

void parseNMEA(char* pt, Nmea_t *ln, double ts)
{
	long i, result;
	long s = 0 ;
	char buffer[3] = {'0','0','\0'};
	char* line_p = pt + strlen(pt) + 1;
	//char sumBuf[3] 
	if (strchr(line_p, '*') == NULL)
	{
		return;
	}

	for (result = line_p[1], i = 2; line_p[i] != '*'; i++){
		result ^= line_p[i];
	}

	buffer[0] = line_p[i + 1];
	buffer[1] = line_p[i + 2];
	s = HexToDec(buffer);

	if (result == s) { //
		pt = strtok_ct(NULL, ",");
		/*printf("pt nmea l %s %u %u\n", pt,i, strcmp(pt, GNRMC_STR));*/
		if (strstr(pt, GGA_STR))
		{
			ParseGGA(pt, ln, ts);
		}
		else if (strstr(pt, RMC_STR))
		{
			ParseRMC(pt, ln, ts);
		}
		else if (strstr(pt, GSV_STR))
		{
			parseGSV(pt, ln, ts);
		}
		else if (strstr(pt, GSA_STR))
		{
			ParseGSA(pt, ln, ts);
		}
		//minTime：应用程序接收GPS更新的最短时间（即只有超过这个时间设定，系统才可能通知我们的程序说“GPS"——单位毫秒
		if ((ln->minTime < 1000) || (ln->minTime > ts))
		{
			ln->minTime = ts;
		}

		if ((ln->maxTime < 1000) || (ln->maxTime < ts))
		{
			ln->maxTime = ts;
		}
	}//
	else {
		printf("unpass  %s", line_p);
	}
}

void preprocessNMEA(Nmea_t *ln)
{
	if (ln->gga.update && (ln->rmc[0].update || ln->rmc[1].update) && (ln->gsa[0].update || ln->gsa[1].update || ln->gsa[2].update)
		&& (ln->gsv[0].update || ln->gsv[1].update || ln->gsv[2].update))
	{
		ln->update = 1;
	}
	else
	{
		NmeaFlag_Init(ln);
	}
}

void ParseGGA(char* pt, Nmea_t *ln, double ts)
{
	if (!strcmp(pt, GNGGA_STR))
	{
		ln->gga.type = SENSOR_LOCATION_NMEA_GNGGA;
		ln->gga.update = 1;
	}
	else if (!strcmp(pt, GPGGA_STR))
	{
		ln->gga.type = SENSOR_LOCATION_NMEA_GPGGA;
		ln->gga.update = 1;
	}
	else
	{
		return;
	}
	int i = 0;
	pt = strtok_ct(NULL, ",");

	while (pt && i < 13)
	{
		if (pt && '\0' == *pt)
		{
			if (0 == i)
			{
				ln->gga.gga_utc = ITEM_INVALID;
			}
			else if (1 == i)
			{
				ln->gga.latitude = ITEM_INVALID;
			}
			else if (2 == i)
			{
				ln->gga.gga_latitude_ns = LATITUDE_N;
			}
			else if (3 == i)
			{
				ln->gga.longitudinal = ITEM_INVALID;

			}
			else if (4 == i)
			{
				ln->gga.longitudinal_ew = LATITUDE_N;
			}
			else if (5 == i)
			{
				ln->gga.status = invalid;
			}
			else if (6 == i)
			{
				ln->gga.satellites_nb = ITEM_INVALID;
			}
			else if (7 == i)
			{
				ln->gga.hdop = ITEM_INVALID;
			}
			else if (8 == i)
			{
				ln->gga.altitude = ITEM_INVALID;
			}
			else if (9 == i)
			{
				ln->gga.unit_a = ITEM_INVALID;
			}
			else if (10 == i)
			{
				ln->gga.height = ITEM_INVALID;
			}
			else if (11 == i)
			{
				ln->gga.unit_h = ITEM_INVALID;

			}
			else if (12 == i)
			{
				ln->gga.dgps = ITEM_INVALID;
			}
			else if (13 == i)
			{
				ln->gga.gga_check_sum[0] = '\0';
			}
		}
		else
		{
			if (0 == i)
			{
				ln->gga.gga_utc = atof(pt);
			}
			else if (1 == i)
			{
				ln->gga.latitude = atof(pt);
			}
			else if (2 == i)
			{
				if (!strcmp(pt, NORTH))
				{
					ln->gga.gga_latitude_ns = LATITUDE_N;
				}
				else if (!strcmp(pt, SOUTH))
				{
					ln->gga.gga_latitude_ns = LATITUDE_S;
				}
			}
			else if (3 == i)
			{
				ln->gga.longitudinal = atof(pt);

			}
			else if (4 == i)
			{
				if (!strcmp(pt, EAST))
				{
					ln->gga.longitudinal_ew = LONGITUDINAL_E;
				}
				else if (!strcmp(pt, WEST))
				{
					ln->gga.longitudinal_ew = LONGITUDINAL_W;
				}
			}
			else if (5 == i)
			{
				ln->gga.status = (gngga_quality)atoll(pt);
			}
			else if (6 == i)
			{
				ln->gga.satellites_nb = atoi(pt);
			}
			else if (7 == i)
			{
				ln->gga.hdop = (float)atof(pt);
			}
			else if (8 == i)
			{
				ln->gga.altitude = (float)atof(pt);
			}
			else if (9 == i)
			{
				if (!strcmp(pt, "M"))
				{
					ln->gga.unit_a = 1;
				}
			}
			else if (10 == i)
			{
				ln->gga.height = (float)atof(pt);
			}
			else if (11 == i)
			{
				if (!strcmp(pt, "M"))
				{
					ln->gga.unit_h = 1;
				}

			}
		}
		pt = strtok_ct(NULL, ",");
		i++;
		/*printf("pt %s %u\n", pt,i);*/
	}
	ln->gga.time = ts;
}

void ParseRMC(char* pt, Nmea_t *ln, double ts)
{
	int i = 0;
	double temp = 0;
	double rmc_time = 0;
	NmeaRMC_t *rmc = NULL;

	if (!strcmp(pt, GNRMC_STR))
	{
		rmc = &ln->rmc[0];
		RMC_Init(rmc);
		rmc->type = SENSOR_LOCATION_NMEA_GNRMC;
		rmc->update = 1;
	}
	else if (!strcmp(pt, GPRMC_STR))
	{
		rmc = &ln->rmc[1];
		RMC_Init(rmc);
		rmc->type = SENSOR_LOCATION_NMEA_GPRMC;
		rmc->update = 1;
	}
	else
	{
		return;
	}

	pt = strtok_ct(NULL, ",");

	while (pt && 12>i)
	{
		if (strlen(pt) > 0)
		{
			if (0 == i)
			{
				rmc_time = atof(pt);
				rmc->rmc_utc = rmc_time;
			}
			else if (1 == i)
			{
				if (!strcmp(pt, "V"))
				{
					rmc->status = POSITIONING_N;
				}
				else if (!strcmp(pt, "A"))
				{
					rmc->status = POSITIONING_Y;
				}
			}
			else if (2 == i)
			{
				temp = atof(pt);
				rmc->latitude = (floor(temp / 100) + (temp - floor(temp / 100) * 100) / 60);
			}
			else if (3 == i)
			{
				if (!strcmp(pt, NORTH))
				{
					rmc->rmc_latitude_ns = LATITUDE_N;
				}
				else if (!strcmp(pt, SOUTH))
				{
					rmc->rmc_latitude_ns = LATITUDE_S;
				}
			}
			else if (4 == i)
			{
				temp = atof(pt);
				rmc->longitudinal = (floor(temp / 100) + (temp - floor(temp / 100) * 100) / 60);
			}
			else if (5 == i)
			{
				if (!strcmp(pt, EAST))
				{
					rmc->longitudinal_ew = LONGITUDINAL_E;
				}
				else if (!strcmp(pt, WEST))
				{
					rmc->longitudinal_ew = LONGITUDINAL_W;
				}
			}
			else if (6 == i)
			{
				rmc->speed = (float)atof(pt);
			}
			else if (7 == i)
			{
				rmc->cog = (float)atof(pt);
			}
			else if (8 == i)
			{
				rmc->utc_ddmmyy = (float)atof(pt);
			}
			else if (9 == i)
			{
				rmc->magnetic = (float)atof(pt);
			}
			else if (10 == i)
			{
				if (!strcmp(pt, EAST))
				{
					rmc->mag_h = MAG_E;
				}
				else if (!strcmp(pt, WEST))
				{
					rmc->mag_h = MAG_W;
				}
			}
			else if (11 == i)
			{
				if (!strcmp(pt, "A"))
				{
					rmc->mode = MODE_A;
				}
				else if (!strcmp(pt, "D"))
				{
					rmc->mode = MODE_D;
				}
				else if (!strcmp(pt, "E"))
				{
					rmc->mode = MODE_E;
				}
				else if (!strcmp(pt, "N"))
				{
					rmc->mode = MODE_N;
				}
			}
			else if (12 == i)
			{
			}
		}
		pt = strtok_ct(NULL, ",");
		i++;
	}
	rmc->time = ts;
}

void parseGSV(char* pt, Nmea_t *ln, double ts)
{
	char *pt_gsv = NULL;

	//memset(&ln->gsv, ITEM_INVALID, sizeof(ln->gsv));
	int i = 0;
	NmeaGSV_t* gsv = NULL;
	if (!strcmp(pt, GPGSV_STR))
	{
		gsv = &ln->gsv[0];
		gsv->type = SENSOR_LOCATION_NMEA_GPGSV;
	}
	else if (!strcmp(pt, GLGSV_STR))
	{
		gsv = &ln->gsv[1];
		gsv->type = SENSOR_LOCATION_NMEA_GLGSV;
	}
	else if (!strcmp(pt, GAGSV_STR))
	{
		gsv = &ln->gsv[2];
		gsv->type = SENSOR_LOCATION_NMEA_GAGSV;
	}
	else
	{
		return;
	}

	/*printf("gsv %s %d\n", pt, gsv->type);*/
	/*printf("nmea rmc %s %u %u\n", pt, !strcmp(pt, GNRMC_STR), rmc->type);*/
	pt = strtok_ct(NULL, ",");
	while (pt && 3>i)
	{
		if (0 == i)
		{
			gsv->sentences = atoi(pt); //total 
		}
		else if (1 == i)
		{
			gsv->sentence_number = atoi(pt);   // Which term of
			if (1 == gsv->sentence_number)
			{
				gsv->satellite_number = 0;
			}
		}
		else if (2 == i)
		{
			gsv->satellites = atoi(pt);  //total 
			break;
		}

		pt = strtok_ct(NULL, ",");
		i++;
	}

	pt_gsv = strtok_ct(NULL, "*");

	pt = strtok_ct(pt_gsv, ",");
	i = 0;

	while (pt && 16>i && gsv->satellites > 0)
	{
		if (pt && '\0' == *pt)
		{
			if (0 == i % 4)
			{
				gsv->satellites_data[gsv->satellite_number].prn = ITEM_INVALID;
			}
			else if (1 == i % 4)
			{
				gsv->satellites_data[gsv->satellite_number].elevation = ITEM_INVALID;
			}
			else if (2 == i % 4)
			{
				gsv->satellites_data[gsv->satellite_number].azimuth = ITEM_INVALID;
			}
			else if (3 == i % 4)
			{
				gsv->satellites_data[gsv->satellite_number].snr = ITEM_INVALID;
				if (gsv->satellite_number < gsv->satellites)   //satellite_number是第几个;satellites是总共的个数
				{
					gsv->satellite_number++;
					if (gsv->satellite_number == gsv->satellites)
					{
						break;
					}
				}
			}
		}
		else
		{
			if (0 == i % 4)
			{
				gsv->satellites_data[gsv->satellite_number].prn = atoi(pt);
				if (gsv->type == SENSOR_LOCATION_NMEA_GPGSV && gsv->satellites_data[gsv->satellite_number].prn > 32)
				{
					gsv->satellites_data[gsv->satellite_number].prn = (gsv->satellites_data[gsv->satellite_number].prn % 32) + 1;
				}
				if (gsv->type == SENSOR_LOCATION_NMEA_GLGSV && gsv->satellites_data[gsv->satellite_number].prn < 65 && gsv->satellites_data[gsv->satellite_number].prn > 99)
				{
					gsv->satellites_data[gsv->satellite_number].prn = (gsv->satellites_data[gsv->satellite_number].prn % 35) + 65;
				}
				if (gsv->type == SENSOR_LOCATION_NMEA_GAGSV && gsv->satellites_data[gsv->satellite_number].prn > 36)
				{
					gsv->satellites_data[gsv->satellite_number].prn = (gsv->satellites_data[gsv->satellite_number].prn % 36) + 1;
				}
			}
			else if (1 == i % 4)
			{
				gsv->satellites_data[gsv->satellite_number].elevation = atoi(pt); //仰角
			}
			else if (2 == i % 4)
			{

				gsv->satellites_data[gsv->satellite_number].azimuth = atoi(pt);
			}
			else if (3 == i % 4)
			{
				gsv->satellites_data[gsv->satellite_number].snr = atoi(pt);
				// printf("2.gsv->satellites_data[gsv->satellite_number]: %d %d %d %d\n", gsv->satellites_data[gsv->satellite_number].prn, gsv->satellites_data[gsv->satellite_number].elevation, gsv->satellites_data[gsv->satellite_number].azimuth, gsv->satellites_data[gsv->satellite_number].snr);
				if (gsv->satellite_number<gsv->satellites)   //satellite_number是第几个;satellites是总共的个数
				{
					gsv->satellite_number++;
					if (gsv->satellite_number == gsv->satellites)
					{
						break;
					}
				}
			}
			//printf("2.gsv->satellites_data[gsv->satellite_number]: %d %d %d %d\n", gsv->satellites_data[gsv->satellite_number].prn, gsv->satellites_data[gsv->satellite_number].elevation, gsv->satellites_data[gsv->satellite_number].azimuth, gsv->satellites_data[gsv->satellite_number].snr);
		}

		pt = strtok_ct(NULL, ",");
		i++;
	}
	if (3 == i % 4 && !pt)
	{
		gsv->satellites_data[gsv->satellite_number].snr = ITEM_INVALID;
		if (gsv->satellite_number<gsv->satellites)
		{
			gsv->satellite_number++;
		}
	}

	if (gsv->satellites == gsv->satellite_number)
	{
		gsv->update = 1;
		//printf_nmea(gsv->type,ln,PrintLOG_file_name);
	}

	gsv->time = ts;
}

void ParseGSA(char* pt, Nmea_t *ln, double ts)
{
	int i = 0;
	int idx = -1;
	NmeaGSA_t gsa = {0};
	if (!strcmp(pt, GNGSA_STR))
	{
		gsa.type = SENSOR_LOCATION_NMEA_GNGSA;
		gsa.update = 1;
	}
	else if (!strcmp(pt, GPGSA_STR))
	{
		idx = 0;
		gsa.type = SENSOR_LOCATION_NMEA_GPGSA;
		gsa.update = 1;
	}
	else if (!strcmp(pt, GLGSA_STR))
	{
		idx = 1;
        gsa.type = SENSOR_LOCATION_NMEA_GLGSA;
		gsa.update = 1;
	}
	else if (!strcmp(pt, GAGSA_STR))
	{
		idx = 2;
        gsa.type = SENSOR_LOCATION_NMEA_GAGSA;
		gsa.update = 1;
	}
	else
	{
		return;
	}

	// printf("gsa %s %d\n", pt, ln->gsa.type);
	pt = strtok_ct(NULL, ",");
	/*printf("nmea gngsa %s %u\n", pt, i);*/
	while (pt && 17>=i)
	{
		/*printf("%u gsa pt %s\n", i, pt);*/
		if (strlen(pt) > 0)
		{
			if (0 == i)
			{
				if (!strcmp(pt, "A"))
				{
					gsa.mode = POSITIONING_MODE_A;
				}
				else if (!strcmp(pt, "M"))
				{
					gsa.mode = POSITIONING_MODE_M;
				}
			}
			else if (1 == i)
			{
				gsa.p_type = (lct_type)atoll(pt);
			}
			else if (( i >= 2 ) && ( i <= 13 ))
			{
				gsa.prn[i - 2] = atoi(pt);

				if (idx == 0 && gsa.prn[i - 2] > 32)
				{
					gsa.prn[i - 2] = (gsa.prn[i - 2] % 32)+1;
				}
				if (idx == 1 && gsa.prn[i - 2] < 65 && gsa.prn[i - 2] > 99)
				{
					gsa.prn[i - 2] = (gsa.prn[i - 2] % 35) + 65;
				}
				if (idx == 2 && gsa.prn[i - 2] > 36)
				{
					gsa.prn[i - 2] = (gsa.prn[i - 2] % 36)+1;
				}
				if (gsa.prn[i - 2] > 64)
				{
					gsa.prnflg |= (1 << (gsa.prn[i - 2] - 64));
					if (idx < 0)
					{
						idx = 1;
					}
				}
				else
				{
					gsa.prnflg |= (1 << gsa.prn[i - 2]);
					if (idx < 0)
					{
						if (ln->gsa[0].update && ln->gsa[1].update)
						{
							idx = 2;
						}
						else
						{
							idx = 0;
						}
					}
				}
			}else if (i == 14){
				gsa.pdop = (float)atof(pt);
			}else if (i == 15){
				gsa.hdop = (float)atof(pt);
			}else if (i == 16){
				gsa.vdop = (float)atof(pt);
			}else if (17 == i)
			{
				if (idx < 0 && pt[0] == '1')
				{
					idx = 0;
                    gsa.type = SENSOR_LOCATION_NMEA_GPGSA;
				}
				else if (idx < 0 && pt[0] == '2')
				{
					idx = 1;
                    gsa.type = SENSOR_LOCATION_NMEA_GLGSA;
				}
				else if (idx < 0 && pt[0] == '3')
				{
					idx = 2;
                    gsa.type = SENSOR_LOCATION_NMEA_GAGSA;
				}
			}

		}

		pt = strtok_ct(NULL, ",");
		i++;
		/*printf("pt %s %u\n", pt,i);*/
	}

	gsa.time = ts;
	if (idx >=0 && idx <=2)
	{
		memcpy(&ln->gsa[idx], &gsa, sizeof(NmeaGSA_t));
	}

}

/**----------------------------------------------------------------------
* Function    : parseLocAccuracy
* Description : 解析GPS的Accuracy精度参数
* Date        : 2020/7/9 yuanlin@vivo.com &logzhan
*---------------------------------------------------------------------**/
void parseLocAccuracy(char* pt, Nmea_t *ln, double ts)
{
	int i = 0;
	while (pt && 8>i){
		if ((i == 0) && (!strcmp(pt, "Status"))){			
			pt = strtok_ct(NULL, ",");
			ln->accuracy.status = atoi(pt);
			return;
		}
		if (i == 7){
			ln->accuracy.update = 1;
			ln->accuracy.time = ts;
			if ((pt && '\0' == *pt))
			{
				ln->accuracy.err = -1;
			}
			else if (ln->accuracy.status == -1 || ln->accuracy.status == 2)
			{
				ln->accuracy.err = (float)atof(pt);
			}
			return;
		}
		pt = strtok_ct(NULL, ",");
		i++;
	}
}

/**----------------------------------------------------------------------
* Function    : ParseLineStr
* Description : 解析字符串信息，根据传感器数据类型，选择不同的函数解析
* Date        : 2020/7/9 yuanlin@vivo.com &logzhan
*---------------------------------------------------------------------**/
int ParseGnssInsData(char* line, IMU_t* imu_p, Nmea_t* ln)
{
	char* pt = NULL;
	int i = 0, sstp = -1;
	double ts = 0;
	pt = strtok_ct(line, ",");

	while (pt && i < 2){
		if (i == 0)ts = atoll(pt) * 0.000001;
		else if (i == 1)sstp = atoi(pt);
		pt = strtok_ct(NULL, ",");
		i++;
	}

	switch (sstp)
	{
		case SENSOR_ACC:
		case SENSOR_MAG:
		case SENSOR_GYRO:
			ParseIMU(pt, imu_p, ts, sstp);
			break;
		case SENSOR_LOCATION_STATELLITE:
			break;
		case SENSOR_LOCATION_NETWORK:
			break;
		case SENSOR_LOCATION_NMEA:
			parseNMEA(pt, ln, ts);
			if ((ln->maxTime - ln->minTime) > NAEA_LAST_TIME)
			{
				preprocessNMEA(ln);
			}
			break;
		case SENSOR_LOCATION_FUSION:
			parseLocAccuracy(pt, ln, ts);
			break;
	}
	if ((ln->minTime > 0) && (ts - ln->minTime) > NAEA_LAST_TIME) {
		preprocessNMEA(ln);
	}
	return 0;
}
