int ComReadThread::parse(char *buf, int sz, std::vector<GPS_Sentence> *result) { int last_sentence_p = -1; //as the return value(the index of the last '$') result->resize(0); if(!buf || sz < 1) return last_sentence_p; char *p = buf; while(p - buf < sz) { if(*p == '$') // a sentence start here { last_sentence_p = p-buf; GPS_Sentence sentence; p += readSentence(p, buf + sz - p, &sentence); result->push_back(sentence); } else { p ++; } } return last_sentence_p; }
/******************************************************************** * Read sentence block from the socket...keeps reading sentences * until it encounters !done, !trap or !fatal from the socket ********************************************************************/ struct Block readBlock(int fdSock) { struct Sentence stSentence; struct Block stBlock; initializeBlock(&stBlock); DEBUG ? printf("readBlock\n") : 0; do { stSentence = readSentence(fdSock); DEBUG ? printf("readSentence succeeded.\n") : 0; addSentenceToBlock(&stBlock, &stSentence); DEBUG ? printf("addSentenceToBlock succeeded\n") : 0; } while (stSentence.iReturnValue == 0); DEBUG ? printf("readBlock completed successfully\n") : 0; return stBlock; }
/******************************************************************** * Read a sentence from the socket * A Sentence struct is returned ********************************************************************/ struct Sentence readSentence(int fdSock) { struct Sentence stReturnSentence; char *szWord; int i = 0; int iReturnLength = 0; DEBUG ? printf("readSentence\n") : 0; initializeSentence(&stReturnSentence); while (szWord = readWord(fdSock)) { addWordToSentence(&stReturnSentence, szWord); // check to see if we can get a return value from the API if (strstr(szWord, "!done") != NULL) { DEBUG ? printf("return sentence contains !done\n") : 0; stReturnSentence.iReturnValue = DONE; } else if (strstr(szWord, "!trap") != NULL) { DEBUG ? printf("return sentence contains !trap\n") : 0; stReturnSentence.iReturnValue = TRAP; } else if (strstr(szWord, "!fatal") != NULL) { DEBUG ? printf("return sentence contains !fatal\n") : 0; stReturnSentence.iReturnValue = FATAL; } free(szWord); } // if any errors, get the next sentence if ((stReturnSentence.iReturnValue == TRAP) || (stReturnSentence.iReturnValue == FATAL)) { readSentence(fdSock); } if (DEBUG) { for (i = 0; i < stReturnSentence.iLength; i++) { printf("stReturnSentence.szSentence[%d] = %s\n", i, stReturnSentence.szSentence[i]); } } return stReturnSentence; }
/******************************************************************** * Login to the API * 1 is returned on successful login * 0 is returned on unsuccessful login ********************************************************************/ int login(int fdSock, char *username, char *password) { struct Sentence stReadSentence; struct Sentence stWriteSentence; char *szMD5Challenge; char *szMD5ChallengeBinary; char *szMD5PasswordToSend; char *szLoginUsernameResponseToSend; char *szLoginPasswordResponseToSend; md5_state_t state; md5_byte_t digest[16]; char cNull[1] = { 0 }; writeWord(fdSock, "/login"); writeWord(fdSock, ""); stReadSentence = readSentence(fdSock); DEBUG ? printSentence(&stReadSentence) : 0; if (stReadSentence.iReturnValue != DONE) { //printf("error.\n"); //exit(0); return 0; } // extract md5 string from the challenge sentence szMD5Challenge = strtok(stReadSentence.szSentence[1], "="); szMD5Challenge = strtok(NULL, "="); DEBUG ? printf("MD5 of challenge = %s\n", szMD5Challenge) : 0; // convert szMD5Challenge to binary szMD5ChallengeBinary = md5ToBinary(szMD5Challenge); // get md5 of the password + challenge concatenation md5_init(&state); md5_append(&state, cNull, 1); md5_append(&state, (const md5_byte_t *)password, strlen(password)); md5_append(&state, (const md5_byte_t *)szMD5ChallengeBinary, 16); md5_finish(&state, digest); // convert this digest to a string representation of the hex values // digest is the binary format of what we want to send // szMD5PasswordToSend is the "string" hex format szMD5PasswordToSend = md5DigestToHexString(digest); DEBUG ? printf("szPasswordToSend = %s\n", szMD5PasswordToSend) : 0; // put together the login sentence initializeSentence(&stWriteSentence); addWordToSentence(&stWriteSentence, "/login"); addWordToSentence(&stWriteSentence, "=name="); addPartWordToSentence(&stWriteSentence, username); addWordToSentence(&stWriteSentence, "=response=00"); addPartWordToSentence(&stWriteSentence, szMD5PasswordToSend); free(szMD5ChallengeBinary); free(szMD5PasswordToSend); DEBUG ? printSentence(&stWriteSentence) : 0; writeSentence(fdSock, &stWriteSentence); stReadSentence = readSentence(fdSock); DEBUG ? printSentence(&stReadSentence) : 0; if (stReadSentence.iReturnValue == DONE) { return 1; } else { return 0; } }