00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <sys/types.h>
00030 #include <sys/stat.h>
00031 #include <fcntl.h>
00032 #include <stdio.h>
00033 #include <unistd.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <termios.h>
00037 #include "garmin.h"
00038 #include "nmeagen.h"
00039 #include "exifgen.h"
00040
00041
00042 #define GARMIN_HEADER_SIZE 12
00043 #define GARMIN_MAX_PKTSIZE 512
00044 #define PKTBUF_SIZE 4097
00045
00046 #define D(x) x
00047 #pragma pack(push, 1)
00048 typedef struct {
00049 u_int8_t mPacketType;
00050 u_int8_t mReserved1;
00051 u_int16_t mReserved2;
00052 u_int16_t mPacketId;
00053 u_int16_t mReserved3;
00054 u_int32_t mDataSize;
00055 u_int8_t mData[1];
00056 } Packet_t;
00057 #pragma pack(pop)
00058
00059 int gps_fd;
00060 char pktbuf[PKTBUF_SIZE];
00061 int pktbuf_head = 0, pktbuf_tail = 0;
00062
00063 D800_Pvt_Data_Type lastpvt;
00064 cpo_sat_data lastsatdata[12];
00065 int satdata_valid = 0;
00066
00067 int pktbuf_size() {
00068 return (PKTBUF_SIZE - pktbuf_head + pktbuf_tail) % PKTBUF_SIZE;
00069 }
00070
00071 int pktbuf_peek(char *buf, int n) {
00072 int i;
00073 int mypktbuf_head = pktbuf_head;
00074 for (i = 0; (i < n) && (mypktbuf_head != pktbuf_tail); i++) {
00075 buf[i] = pktbuf[mypktbuf_head];
00076 mypktbuf_head++;
00077 if (mypktbuf_head == PKTBUF_SIZE)
00078 mypktbuf_head = 0;
00079 }
00080 return i;
00081 }
00082
00083 int pktbuf_deq(char *buf, int n) {
00084 int i;
00085
00086 for (i = 0; (i < n) && (pktbuf_head != pktbuf_tail); i++) {
00087 buf[i] = pktbuf[pktbuf_head];
00088 pktbuf_head++;
00089 if (pktbuf_head == PKTBUF_SIZE)
00090 pktbuf_head = 0;
00091 }
00092 return i;
00093 }
00094
00095 int pktbuf_enq(char *buf, int n) {
00096
00097 int i;
00098
00099 if (pktbuf_size() + n >= PKTBUF_SIZE)
00100 return 0;
00101
00102 for (i = 0; i < n; i++) {
00103 pktbuf[pktbuf_tail] = buf[i];
00104 pktbuf_tail++;
00105 if (pktbuf_tail == PKTBUF_SIZE)
00106 pktbuf_tail = 0;
00107 }
00108
00109 return i;
00110 }
00111
00112 int sendpacket(Packet_t *pack) {
00113 int nwr;
00114 nwr = write(gps_fd, pack, GARMIN_HEADER_SIZE + pack->mDataSize);
00115 if (nwr == -1) {
00116 perror("GPS write error");
00117 return 1;
00118 }
00119 return 0;
00120 }
00121
00122 Packet_t* recvpacket(void) {
00123 Packet_t *pkt;
00124 char tmp[64];
00125 int nr;
00126
00127 pkt = (Packet_t*)malloc(GARMIN_MAX_PKTSIZE);
00128 if (pkt == NULL) {
00129 perror("malloc failed");
00130 return NULL;
00131 }
00132
00133 chkbuf:
00134
00135 if (pktbuf_size() >= GARMIN_HEADER_SIZE) {
00136 Packet_t bufpkt;
00137 pktbuf_peek((char*)&bufpkt, GARMIN_HEADER_SIZE);
00138 int pktlen = GARMIN_HEADER_SIZE + bufpkt.mDataSize;
00139 if (pktbuf_size() >= pktlen) {
00140 pktbuf_deq((char*)pkt, pktlen);
00141 return pkt;
00142 }
00143 }
00144
00145
00146 nr = read(gps_fd, tmp, 64);
00147 if (nr == -1) {
00148 perror("GPS read error");
00149 free(pkt);
00150 return NULL;
00151 }
00152 if (pktbuf_enq(tmp, nr) == 0) {
00153 fprintf(stderr, "Input buffer full!\n");
00154
00155
00156 free(pkt);
00157 return NULL;
00158 }
00159 goto chkbuf;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 void garmin_pvton(void) {
00171 Packet_t *pvtpack = (Packet_t*)malloc(14);
00172
00173 pvtpack->mPacketType = 20;
00174 pvtpack->mReserved1 = 0;
00175 pvtpack->mReserved2 = 0;
00176 pvtpack->mPacketId = 10;
00177 pvtpack->mReserved3 = 0;
00178 pvtpack->mDataSize = 2;
00179 pvtpack->mData[0] = 49;
00180 pvtpack->mData[1] = 0;
00181
00182 sendpacket(pvtpack);
00183 }
00184 void garmin_privcmd(int fd) {
00185 u_int32_t privcmd[4];
00186 privcmd[0] = 0x01106E4B;
00187 privcmd[1] = 2;
00188 privcmd[2] = 4;
00189 privcmd[3] = 0;
00190 write(fd, privcmd, 16);
00191 }
00192
00193 #define EXIF_DEV "/dev/exif_meta"
00194
00195 int main(int argc, char *argv[]) {
00196
00197 int fd_exif;
00198 struct meta_GPSInfo_t meta;
00199
00200
00201
00202 struct termios termio;
00203
00204 if (argc < 2) {
00205 printf("Usage: %s gpsdev\n", argv[0]);
00206 return 1;
00207 }
00208
00209 gps_fd = open(argv[1], O_RDWR);
00210 if (gps_fd == -1) {
00211 perror("Cannot open GPS device");
00212 return 1;
00213 }
00214
00215 tcgetattr(gps_fd, &termio);
00216 cfmakeraw(&termio);
00217 tcsetattr(gps_fd, TCIOFLUSH, &termio);
00218 garmin_privcmd(gps_fd);
00219 garmin_pvton();
00220 pktbuf_head = 0;
00221 pktbuf_tail = 0;
00222 fd_exif = open(EXIF_DEV, O_RDWR);
00223 if (fd_exif<=0) {
00224 fprintf(stderr,"Can not open device file "EXIF_DEV);
00225 close(gps_fd);
00226 exit (-1);
00227 }
00228 exif_init_meta(&meta);
00229 while (1) {
00230 Packet_t *pkt = recvpacket();
00231 if (pkt) {
00232 D(printf("Packet ID: %d, head=%d, tail=%d\n", pkt->mPacketId, pktbuf_head, pktbuf_tail));
00233
00234 if (pkt->mPacketId == Pid_Pvt_Data) {
00235 memcpy(&lastpvt, pkt->mData, sizeof(lastpvt));
00236 if (exif_gen(&lastpvt, satdata_valid ? lastsatdata : NULL, &meta) >=0) {
00237 lseek (fd_exif,Exif_GPSInfo_GPSLatitudeRef,SEEK_END);
00238 write (fd_exif, &meta, sizeof(meta));
00239 }
00240 } else if (pkt->mPacketId == Pid_SatData_Record) {
00241 memcpy(lastsatdata, pkt->mData, sizeof(lastsatdata));
00242 satdata_valid = 1;
00243 }
00244 free(pkt);
00245 } else {
00246 fprintf(stderr,"Lost GPS or sync, trying to restart communication and packet buffer. (pktbuf_head=%d,pktbuf_tail=%d)\n",pktbuf_head,pktbuf_tail);
00247 tcsetattr(gps_fd, TCIOFLUSH, &termio);
00248 garmin_privcmd(gps_fd);
00249 garmin_pvton();
00250 pktbuf_head = 0;
00251 pktbuf_tail = 0;
00252 }
00253 }
00254 close(gps_fd);
00255 }