/*
了解GPS相关知识
$GPRMC协议格式
　　例：$GPRMC, 024813.640, A, 3158.4608, N, 11848.3737, E, 10.05, 324.27, 150706, , , A * 50
　　字段0：$GPRMC，语句ID，表明该语句为Recommended Minimum Specific GPS / TRANSIT Data（RMC）推荐最小定位信息
　　字段1：UTC时间，hhmmss.sss格式(UTC时间是世界统一时间，中国的时间是UTC + 8，比如：上面的时间是02 : 48 : 13而中国的时间是10 : 48 : 13)
　　字段2：状态，A = 定位，V = 未定位
　　字段3：纬度ddmm.mmmm，度分格式（前导位数不足则补0） 
　　字段4：纬度N（北纬）或S（南纬）
　　字段5：经度dddmm.mmmm，度分格式（前导位数不足则补0）
　　字段6：经度E（东经）或W（西经）
　　字段7：速度，节，Knots
　　字段8：方位角，度
　　字段9：UTC日期，DDMMYY格式
　　字段10：磁偏角，（000 - 180）度（前导位数不足则补0）
　　字段11：磁偏角方向，E = 东W = 西
　　字段16：校验值

【提示】利用strtok切割、sscanf或者strncpy、atoi、atof
*/
#include <stdio.h>
#include <string.h>

typedef struct
{
    char time[10];        // UTC时间，格式为hhmmss.sss
    char status;          // 状态，A表示定位，V表示未定位
    double latitude;      // 纬度，格式为ddmm.mmmm
    char latitude_dir;    // 纬度半球，N表示北半球，S表示南半球
    double longitude;     // 经度，格式为dddmm.mmmm
    char longitude_dir;   // 经度半球，E表示东经，W表示西经
    double speed;         // 速度，以节为单位
    double course;        // 方位角，以度为单位
    char date[7];         // UTC日期，格式为DDMMYY
    double declination;   // 磁偏角，以度为单位
    char declination_dir; // 磁偏角方向，E表示东偏，W表示西偏
} gprmc_t;

int parse_gprmc(const char *str, gprmc_t *gprmc)
{
    char *token;
    int i = 0;
    token = strtok((char *)str, ",");
    while (token != NULL)
    {
        switch (i)
        {
        case 0:
            if (strcmp(token, "$GPRMC") != 0)
            {
                return -1;
            }
            break;
        case 1:
            sscanf(token, "%2s", gprmc->time);
            sscanf(token + 2, "%2lf%lf", &gprmc->time[2], &gprmc->time[4]);
            sscanf(token + 4, "%lf", &gprmc->time[6]);
            break;
        case 2:
            gprmc->status = *token;
            break;
        case 3:
            sscanf(token, "%lf", &gprmc->latitude);
            sscanf(token + 2, "%lf", &gprmc->latitude);
            break;
        case 4:
            gprmc->latitude_dir = *token;
            break;
        case 5:
            sscanf(token, "%lf", &gprmc->longitude);
            sscanf(token + 3, "%lf", &gprmc->longitude);
            break;
        case 6:
            gprmc->longitude_dir = *token;
            break;
        case 7:
            sscanf(token, "%lf", &gprmc->speed);
            break;
        case 8:
            sscanf(token, "%lf", &gprmc->course);
            break;
        case 9:
            sscanf(token, "%2s", gprmc->date);
            sscanf(token + 2, "%2lf%lf", &gprmc->date[2], &gprmc->date[4]);
            sscanf(token + 4, "%lf", &gprmc->date[6]);
            break;
        case 10:
            sscanf(token, "%lf", &gprmc->declination);
            break;
        case 11:
            gprmc->declination_dir = *token;
            break;
        default:
            break;
        }
        token = strtok(NULL, ",");
        i++;
    }
    return 0;
}

int main()
{
    const char *str = "$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50";
    gprmc_t gprmc;
    if (parse_gprmc(str, &gprmc) == 0)
    {
        printf("UTC时间：%s\n", gprmc.time);
        printf("状态：%c\n", gprmc.status);
        printf("纬度：%lf %c\n", gprmc.latitude, gprmc.latitude_dir);
        printf("经度：%lf %c\n", gprmc.longitude, gprmc.longitude_dir);
        printf("速度：%lf\n", gprmc.speed);
        printf("方位角：%lf\n", gprmc.course);
        printf("UTC日期：%s\n", gprmc.date);
        printf("磁偏角：%lf %c\n", gprmc.declination, gprmc.declination_dir);
    }
    return 0;
}
