// // Convert a text TLE ephemeris file into a pocketSat input database // // usage: tle2pdb tleFile pdbFile dbName // // NOTE: make sure that your compiler byte-aligns when you build this. // Actually, word-alignment may be OK. Since there isn't a time/size constraint // I just went with bytes. // #include #include #include #include // // palm PDB file structure // #define UWord unsigned short #define ULong unsigned long #define UByte unsigned char #define DBNAME_LEN 32 // DB attributes #define DB_READONLY 0x0002 #define DB_OVERWRITE 0x0010 typedef struct _pdbhead { char name[DBNAME_LEN]; // needs null terminator UWord attr; UWord version; ULong cdate; ULong mdate; ULong bdate; ULong modNum; ULong appInfoOffset; ULong sortInfoOffset; char dbType[4]; char creatorID[4]; ULong idSeed; ULong nextRecListID; UWord numRec; } PDBHeader; typedef struct _reclistentry { ULong recOffset; UByte attrAndID[4]; } RecordListEntry; // // ID and type // #define CREATOR_ID "pSat" #define DB_TYPE "iTLE" #define MAX_RECS 3000 // that would be 1000 satellites // I'm pretty sure these swap functions work automagically. // I've used this method before and it worked, but I don't have // access to a Motorola-based platform to test on. UWord order = 'MI'; UWord MSBWord(UWord in) { UWord res; char* pC = (char*)ℴ if (*pC == 'M') return in; res = (in >> 8) + ((in & 0xff)<<8); return res; } ULong MSBLong(ULong in) { ULong res; char* pC = (char*)ℴ if (*pC == 'M') return in; res = (in >> 24) + ((in & 0x00ff0000) >> 8) + ((in & 0x0000ff00) << 8) + ((in & 0x000000ff) << 24); return res; } // Should be secs since Jan 1, 1904 //(or so the docs claim. Actually, from looking at PDB headers, // it seems to be from 1/1/1970) ULong PalmSecsNow(void) { ULong t = time(&t); // since Jan 1, 1970 return t; } void main(int argc, char** argv) { FILE* inFile; FILE* outFile; char dbName[DBNAME_LEN]; char* inRecs[MAX_RECS]; char inBuff[132]; UWord recCount; PDBHeader head; RecordListEntry* recList; ULong dataLoc; int i; if (argc < 3) { puts("usage: tle2pdb inputFile outputFile databaseName"); puts(" ie: tle2pdb sats.tle sats.pdb NewSatellites"); return; } if ((inFile = fopen(argv[1], "rt")) == NULL) { perror("Can't open input file"); return; } if ((outFile = fopen(argv[2], "wb")) == NULL) { perror("Can't open output file"); fclose(inFile); return; } strncpy(dbName,argv[3], DBNAME_LEN); dbName[DBNAME_LEN-1] = 0; // pretty small files, so just read it all in while counting recs recCount = 0; while( fgets(inBuff, 132, inFile) != NULL) { int n = strlen(inBuff); inRecs[recCount] = malloc(n+1); strcpy(inRecs[recCount],inBuff); recCount++; if (recCount == MAX_RECS) { puts("Too many input records. Data truncated."); break; } } fclose(inFile); // initialize the header strcpy(head.name, dbName); //head.attr = MSBWord( DB_OVERWRITE); head.attr = 0; head.version = MSBWord(1); head.cdate = MSBLong(PalmSecsNow()); head.mdate = head.cdate; head.bdate = 0; head.modNum = 0; head.appInfoOffset = 0; head.sortInfoOffset = 0; memcpy(head.dbType,DB_TYPE,4); memcpy(head.creatorID,CREATOR_ID,4); head.idSeed = 0; head.nextRecListID = 0; head.numRec = MSBWord(recCount); // create and fill the record list block recList = (RecordListEntry*)malloc( recCount*sizeof(RecordListEntry)); dataLoc = sizeof(PDBHeader) + recCount * sizeof(RecordListEntry); for(i=0;i