SQL Client with VodafoneUSBModem

Fork of MySQLClient by Donatien Garnier

Committer:
loc_tran17
Date:
Fri Nov 22 09:32:56 2013 +0000
Revision:
8:cdb6d1236f37
Parent:
6:e8f34b496ab0
try SQLClient

Who changed what in which revision?

UserRevisionLine numberNew contents of line
loc_tran17 6:e8f34b496ab0 1
loc_tran17 6:e8f34b496ab0 2
loc_tran17 6:e8f34b496ab0 3 /*
loc_tran17 6:e8f34b496ab0 4 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
loc_tran17 6:e8f34b496ab0 5
loc_tran17 6:e8f34b496ab0 6 Permission is hereby granted, free of charge, to any person obtaining a copy
loc_tran17 6:e8f34b496ab0 7 of this software and associated documentation files (the "Software"), to deal
loc_tran17 6:e8f34b496ab0 8 in the Software without restriction, including without limitation the rights
loc_tran17 6:e8f34b496ab0 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
loc_tran17 6:e8f34b496ab0 10 copies of the Software, and to permit persons to whom the Software is
loc_tran17 6:e8f34b496ab0 11 furnished to do so, subject to the following conditions:
loc_tran17 6:e8f34b496ab0 12
loc_tran17 6:e8f34b496ab0 13 The above copyright notice and this permission notice shall be included in
loc_tran17 6:e8f34b496ab0 14 all copies or substantial portions of the Software.
loc_tran17 6:e8f34b496ab0 15
loc_tran17 6:e8f34b496ab0 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
loc_tran17 6:e8f34b496ab0 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
loc_tran17 6:e8f34b496ab0 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
loc_tran17 6:e8f34b496ab0 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
loc_tran17 6:e8f34b496ab0 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
loc_tran17 6:e8f34b496ab0 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
loc_tran17 6:e8f34b496ab0 22 THE SOFTWARE.
loc_tran17 6:e8f34b496ab0 23 */
loc_tran17 6:e8f34b496ab0 24
loc_tran17 6:e8f34b496ab0 25 #include "mycrypt.h"
loc_tran17 6:e8f34b496ab0 26 #include "sha1.h"
loc_tran17 6:e8f34b496ab0 27 #include "MySQLClient.h"
loc_tran17 6:e8f34b496ab0 28
loc_tran17 6:e8f34b496ab0 29 //#define __DEBUG
loc_tran17 6:e8f34b496ab0 30
loc_tran17 6:e8f34b496ab0 31
loc_tran17 6:e8f34b496ab0 32 #define MYSQL_TIMEOUT_MS 45000
loc_tran17 6:e8f34b496ab0 33 #define MYSQL_PORT 3306
loc_tran17 6:e8f34b496ab0 34
loc_tran17 6:e8f34b496ab0 35 #define BUF_SIZE 256
loc_tran17 6:e8f34b496ab0 36
loc_tran17 6:e8f34b496ab0 37 #define CLIENT_LONG_PASSWORD 1
loc_tran17 6:e8f34b496ab0 38 #define CLIENT_CONNECT_WITH_DB 8
loc_tran17 6:e8f34b496ab0 39 #define CLIENT_PROTOCOL_41 512
loc_tran17 6:e8f34b496ab0 40 #define CLIENT_INTERACTIVE 1024
loc_tran17 6:e8f34b496ab0 41 #define CLIENT_SECURE_CONNECTION 32768
loc_tran17 6:e8f34b496ab0 42
loc_tran17 6:e8f34b496ab0 43 #define MIN(a,b) ((a)<(b)?(a):(b))
loc_tran17 6:e8f34b496ab0 44 #define ABS(a) (((a)>0)?(a):0)
loc_tran17 6:e8f34b496ab0 45
loc_tran17 6:e8f34b496ab0 46 //MySQL commands
loc_tran17 6:e8f34b496ab0 47 #define COM_QUIT 0x01 //Exit
loc_tran17 6:e8f34b496ab0 48 #define COM_QUERY 0x03 //Execute an SQL query
loc_tran17 6:e8f34b496ab0 49
loc_tran17 6:e8f34b496ab0 50 //#define htons( x ) ( (( x << 8 ) & 0xFF00) | (( x >> 8 ) & 0x00FF) )
loc_tran17 6:e8f34b496ab0 51 #define ntohs( x ) (htons(x))
loc_tran17 6:e8f34b496ab0 52
loc_tran17 6:e8f34b496ab0 53 /*#define htonl( x ) ( (( x << 24 ) & 0xFF000000) \
loc_tran17 6:e8f34b496ab0 54 | (( x << 8 ) & 0x00FF0000) \
loc_tran17 6:e8f34b496ab0 55 | (( x >> 8 ) & 0x0000FF00) \
loc_tran17 6:e8f34b496ab0 56 | (( x >> 24 ) & 0x000000FF) )*/
loc_tran17 6:e8f34b496ab0 57 #define htonl( x ) (x)
loc_tran17 6:e8f34b496ab0 58 #define ntohl( x ) (htonl(x))
loc_tran17 6:e8f34b496ab0 59
loc_tran17 6:e8f34b496ab0 60 MySQLClient::MySQLClient() : m_pCbItem(NULL), m_pCbMeth(NULL), m_pCb(NULL),
loc_tran17 6:e8f34b496ab0 61 m_pTCPSocket(NULL), m_watchdog(), m_timeout(MYSQL_TIMEOUT_MS*1000), m_closed(true),
loc_tran17 6:e8f34b496ab0 62 m_user(), m_password(), m_db(), m_state(MYSQL_CLOSED)
loc_tran17 6:e8f34b496ab0 63 {
loc_tran17 6:e8f34b496ab0 64 m_buf = new byte[BUF_SIZE];
loc_tran17 6:e8f34b496ab0 65 m_pPos = m_buf;
loc_tran17 6:e8f34b496ab0 66 m_len = 0;
loc_tran17 6:e8f34b496ab0 67 m_size = BUF_SIZE;
loc_tran17 6:e8f34b496ab0 68 }
loc_tran17 6:e8f34b496ab0 69
loc_tran17 6:e8f34b496ab0 70 MySQLClient::~MySQLClient()
loc_tran17 6:e8f34b496ab0 71 {
loc_tran17 6:e8f34b496ab0 72 close();
loc_tran17 6:e8f34b496ab0 73 delete[] m_buf;
loc_tran17 6:e8f34b496ab0 74 }
loc_tran17 6:e8f34b496ab0 75
loc_tran17 6:e8f34b496ab0 76 //High Level setup functions
loc_tran17 6:e8f34b496ab0 77 MySQLResult MySQLClient::open(const string& host, int port, const string& user, const string& password, const string& db, void (*pMethod)(MySQLResult)) //Non blocking
loc_tran17 6:e8f34b496ab0 78 {
loc_tran17 6:e8f34b496ab0 79 setOnResult(pMethod);
loc_tran17 6:e8f34b496ab0 80 setup(host, port, user, password, db);
loc_tran17 6:e8f34b496ab0 81 return MYSQL_PROCESSING;
loc_tran17 6:e8f34b496ab0 82 }
loc_tran17 6:e8f34b496ab0 83
loc_tran17 6:e8f34b496ab0 84 MySQLResult MySQLClient::sql(string& sqlCommand)
loc_tran17 6:e8f34b496ab0 85 {
loc_tran17 6:e8f34b496ab0 86 if(m_state!=MYSQL_COMMANDS)
loc_tran17 6:e8f34b496ab0 87 return MYSQL_SETUP;
loc_tran17 6:e8f34b496ab0 88 sendCommand(COM_QUERY, (byte*)sqlCommand.data(), sqlCommand.length());
loc_tran17 6:e8f34b496ab0 89 return MYSQL_PROCESSING;
loc_tran17 6:e8f34b496ab0 90 }
loc_tran17 6:e8f34b496ab0 91
loc_tran17 6:e8f34b496ab0 92 MySQLResult MySQLClient::exit()
loc_tran17 6:e8f34b496ab0 93 {
loc_tran17 6:e8f34b496ab0 94 sendCommand(COM_QUIT, NULL, 0);
loc_tran17 6:e8f34b496ab0 95 close();
loc_tran17 6:e8f34b496ab0 96 return MYSQL_OK;
loc_tran17 6:e8f34b496ab0 97 }
loc_tran17 6:e8f34b496ab0 98
loc_tran17 6:e8f34b496ab0 99 void MySQLClient::setOnResult( void (*pMethod)(MySQLResult) )
loc_tran17 6:e8f34b496ab0 100 {
loc_tran17 6:e8f34b496ab0 101 m_pCb = pMethod;
loc_tran17 6:e8f34b496ab0 102 m_pCbItem = NULL;
loc_tran17 6:e8f34b496ab0 103 m_pCbMeth = NULL;
loc_tran17 6:e8f34b496ab0 104 }
loc_tran17 6:e8f34b496ab0 105
loc_tran17 8:cdb6d1236f37 106
loc_tran17 6:e8f34b496ab0 107 void MySQLClient::setTimeout(int ms)
loc_tran17 6:e8f34b496ab0 108 {
loc_tran17 6:e8f34b496ab0 109 m_timeout = 1000*ms;
loc_tran17 6:e8f34b496ab0 110 }
loc_tran17 6:e8f34b496ab0 111
loc_tran17 6:e8f34b496ab0 112 void MySQLClient::poll() //Called by NetServices
loc_tran17 6:e8f34b496ab0 113 {
loc_tran17 6:e8f34b496ab0 114 if(m_closed)
loc_tran17 6:e8f34b496ab0 115 {
loc_tran17 6:e8f34b496ab0 116 return;
loc_tran17 6:e8f34b496ab0 117 }
loc_tran17 6:e8f34b496ab0 118 if(m_watchdog.read_us()>m_timeout)
loc_tran17 6:e8f34b496ab0 119 {
loc_tran17 6:e8f34b496ab0 120 onTimeout();
loc_tran17 6:e8f34b496ab0 121 }
loc_tran17 6:e8f34b496ab0 122 }
loc_tran17 6:e8f34b496ab0 123
loc_tran17 6:e8f34b496ab0 124 void MySQLClient::resetTimeout()
loc_tran17 6:e8f34b496ab0 125 {
loc_tran17 6:e8f34b496ab0 126 m_watchdog.reset();
loc_tran17 6:e8f34b496ab0 127 m_watchdog.start();
loc_tran17 6:e8f34b496ab0 128 }
loc_tran17 6:e8f34b496ab0 129
loc_tran17 6:e8f34b496ab0 130 void MySQLClient::init()
loc_tran17 6:e8f34b496ab0 131 {
loc_tran17 6:e8f34b496ab0 132 close(); //Remove previous elements
loc_tran17 6:e8f34b496ab0 133 if(!m_closed) //Already opened
loc_tran17 6:e8f34b496ab0 134 return;
loc_tran17 6:e8f34b496ab0 135 m_state = MYSQL_HANDSHAKE;
loc_tran17 6:e8f34b496ab0 136 m_pTCPSocket = new TCPSocketConnection;
loc_tran17 6:e8f34b496ab0 137 m_closed = false;
loc_tran17 6:e8f34b496ab0 138 }
loc_tran17 6:e8f34b496ab0 139
loc_tran17 6:e8f34b496ab0 140 void MySQLClient::close()
loc_tran17 6:e8f34b496ab0 141 {
loc_tran17 6:e8f34b496ab0 142 if(m_closed)
loc_tran17 6:e8f34b496ab0 143 return;
loc_tran17 6:e8f34b496ab0 144 m_state = MYSQL_CLOSED;
loc_tran17 6:e8f34b496ab0 145 m_closed = true; //Prevent recursive calling or calling on an object being destructed by someone else
loc_tran17 6:e8f34b496ab0 146 m_watchdog.stop(); //Stop timeout
loc_tran17 6:e8f34b496ab0 147 m_watchdog.reset();
loc_tran17 6:e8f34b496ab0 148 m_pTCPSocket->close();
loc_tran17 6:e8f34b496ab0 149 delete m_pTCPSocket;
loc_tran17 6:e8f34b496ab0 150 m_pTCPSocket = NULL;
loc_tran17 6:e8f34b496ab0 151 }
loc_tran17 6:e8f34b496ab0 152
loc_tran17 6:e8f34b496ab0 153 void MySQLClient::setup(const string& host, int port, const string& user, const string& password, const string& db) //Setup connection, make DNS Req if necessary
loc_tran17 6:e8f34b496ab0 154 {
loc_tran17 6:e8f34b496ab0 155 init(); //Initialize client in known state, create socket
loc_tran17 6:e8f34b496ab0 156 resetTimeout();
loc_tran17 8:cdb6d1236f37 157
loc_tran17 6:e8f34b496ab0 158 m_host = host;
loc_tran17 6:e8f34b496ab0 159 m_port = port;
loc_tran17 6:e8f34b496ab0 160 m_user = user;
loc_tran17 6:e8f34b496ab0 161 m_password = password;
loc_tran17 6:e8f34b496ab0 162
loc_tran17 6:e8f34b496ab0 163 m_db = db;
loc_tran17 8:cdb6d1236f37 164 connect();
loc_tran17 6:e8f34b496ab0 165 }
loc_tran17 6:e8f34b496ab0 166
loc_tran17 6:e8f34b496ab0 167 void MySQLClient::connect() //Start Connection
loc_tran17 6:e8f34b496ab0 168 {
loc_tran17 6:e8f34b496ab0 169 char host[128];
loc_tran17 6:e8f34b496ab0 170
loc_tran17 6:e8f34b496ab0 171 resetTimeout();
loc_tran17 6:e8f34b496ab0 172 printf("Connecting...");
loc_tran17 6:e8f34b496ab0 173
loc_tran17 6:e8f34b496ab0 174 strcpy(host, m_host.c_str());
loc_tran17 6:e8f34b496ab0 175 m_pTCPSocket->connect(host, m_port);
loc_tran17 6:e8f34b496ab0 176
loc_tran17 6:e8f34b496ab0 177 printf("OK \n");
loc_tran17 6:e8f34b496ab0 178 m_packetId = 0;
loc_tran17 6:e8f34b496ab0 179 }
loc_tran17 6:e8f34b496ab0 180
loc_tran17 6:e8f34b496ab0 181 void MySQLClient::handleHandshake()
loc_tran17 6:e8f34b496ab0 182 {
loc_tran17 6:e8f34b496ab0 183 readData();
loc_tran17 6:e8f34b496ab0 184 if( ! (( m_len > 1 ) && ( memchr( m_buf + 1, 0, m_len ) != NULL )) )
loc_tran17 6:e8f34b496ab0 185 {
loc_tran17 6:e8f34b496ab0 186 printf("Connected but could not find pcsz...\n");
loc_tran17 6:e8f34b496ab0 187 onResult(MYSQL_PRTCL);
loc_tran17 6:e8f34b496ab0 188 return;
loc_tran17 6:e8f34b496ab0 189 }
loc_tran17 6:e8f34b496ab0 190
loc_tran17 6:e8f34b496ab0 191 printf("Connected to server: %d bytes read ; Protocol version %d, mysql-%s.\n", m_len, m_buf[0], &m_buf[1]);
loc_tran17 6:e8f34b496ab0 192
loc_tran17 6:e8f34b496ab0 193 m_pPos = (byte*) memchr( (char*)(m_buf + 1), 0, m_len ) + 1;
loc_tran17 6:e8f34b496ab0 194
loc_tran17 6:e8f34b496ab0 195 sendAuth();
loc_tran17 6:e8f34b496ab0 196 }
loc_tran17 6:e8f34b496ab0 197
loc_tran17 6:e8f34b496ab0 198 void MySQLClient::sendAuth()
loc_tran17 6:e8f34b496ab0 199 {
loc_tran17 6:e8f34b496ab0 200 if( m_len - (m_pPos - m_buf) != 44)
loc_tran17 6:e8f34b496ab0 201 {
loc_tran17 6:e8f34b496ab0 202 //We only support protocol >= mysql-4.1
loc_tran17 6:e8f34b496ab0 203 printf("Message after pcsz has wrong len (%d != 44)...\n", m_len - (m_pPos - m_buf));
loc_tran17 6:e8f34b496ab0 204 onResult(MYSQL_PRTCL);
loc_tran17 6:e8f34b496ab0 205 return;
loc_tran17 6:e8f34b496ab0 206 }
loc_tran17 6:e8f34b496ab0 207
loc_tran17 6:e8f34b496ab0 208 uint16_t serverFlags = *((uint16_t*)&m_pPos[13]);
loc_tran17 6:e8f34b496ab0 209 printf("Server capabilities are %04X.\n", serverFlags);
loc_tran17 6:e8f34b496ab0 210
loc_tran17 6:e8f34b496ab0 211 uint32_t clientFlags = CLIENT_CONNECT_WITH_DB | CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | CLIENT_INTERACTIVE;;
loc_tran17 6:e8f34b496ab0 212
loc_tran17 6:e8f34b496ab0 213 //if(serverFlags & CLIENT_LONG_PASSWORD)
loc_tran17 6:e8f34b496ab0 214
loc_tran17 6:e8f34b496ab0 215 printf("Using auth 4.1+\n");
loc_tran17 6:e8f34b496ab0 216 //Encrypt pw using scramble
loc_tran17 6:e8f34b496ab0 217 byte scramble[20+20]={0};
loc_tran17 6:e8f34b496ab0 218 memcpy(scramble, m_pPos+4, 8);
loc_tran17 6:e8f34b496ab0 219 memcpy(scramble+8, m_pPos+31, 12); // *(m_pPos+43) == 0 (zero-terminated char*)
loc_tran17 6:e8f34b496ab0 220
loc_tran17 6:e8f34b496ab0 221 byte stage1_hash[20] = {0};
loc_tran17 6:e8f34b496ab0 222 sha1( (byte*)m_password.data(), m_password.length(), stage1_hash );
loc_tran17 6:e8f34b496ab0 223
loc_tran17 6:e8f34b496ab0 224 sha1( stage1_hash, 20, ((byte*)scramble + 20) );
loc_tran17 6:e8f34b496ab0 225
loc_tran17 6:e8f34b496ab0 226 byte token[20] = {0};
loc_tran17 6:e8f34b496ab0 227 sha1( scramble, 40, token );
loc_tran17 6:e8f34b496ab0 228
loc_tran17 6:e8f34b496ab0 229 for(int i=0;i<20;i++)
loc_tran17 6:e8f34b496ab0 230 token[i] = token[i] ^ stage1_hash[i];
loc_tran17 6:e8f34b496ab0 231
loc_tran17 6:e8f34b496ab0 232 clientFlags |= CLIENT_LONG_PASSWORD;
loc_tran17 6:e8f34b496ab0 233
loc_tran17 6:e8f34b496ab0 234 printf("Building response\n");
loc_tran17 6:e8f34b496ab0 235 //Build response
loc_tran17 6:e8f34b496ab0 236
loc_tran17 6:e8f34b496ab0 237 //BE
loc_tran17 6:e8f34b496ab0 238 *((uint32_t*)&m_buf[0]) = htonl(clientFlags);
loc_tran17 6:e8f34b496ab0 239 *((uint32_t*)&m_buf[4]) = BUF_SIZE; //Max packets size
loc_tran17 6:e8f34b496ab0 240 m_buf[8] = 8; //latin1 charset
loc_tran17 6:e8f34b496ab0 241 memset((char*)(m_buf+9),0,23);
loc_tran17 6:e8f34b496ab0 242 strcpy((char*)(m_buf+32),m_user.c_str());
loc_tran17 6:e8f34b496ab0 243 m_pPos = m_buf + 32 + m_user.length() + 1;
loc_tran17 6:e8f34b496ab0 244 m_pPos[0] = 20;
loc_tran17 6:e8f34b496ab0 245 memcpy((char*)&m_pPos[1],token,20);
loc_tran17 6:e8f34b496ab0 246 strcpy((char*)(m_pPos+21),m_db.c_str());
loc_tran17 6:e8f34b496ab0 247 m_len = 32 + m_user.length() + 1 + 21 + m_db.length() + 1;
loc_tran17 6:e8f34b496ab0 248
loc_tran17 6:e8f34b496ab0 249 //Save first part of scramble in case we need it again
loc_tran17 6:e8f34b496ab0 250 memcpy(&m_buf[BUF_SIZE-8], scramble, 8);
loc_tran17 6:e8f34b496ab0 251
loc_tran17 6:e8f34b496ab0 252 m_state = MYSQL_AUTH;
loc_tran17 6:e8f34b496ab0 253
loc_tran17 6:e8f34b496ab0 254 printf("Writing data\n");
loc_tran17 6:e8f34b496ab0 255 writeData();
loc_tran17 6:e8f34b496ab0 256 }
loc_tran17 6:e8f34b496ab0 257
loc_tran17 6:e8f34b496ab0 258 void MySQLClient::handleAuthResult()
loc_tran17 6:e8f34b496ab0 259 {
loc_tran17 6:e8f34b496ab0 260 readData();
loc_tran17 6:e8f34b496ab0 261 if(m_len==1 && *m_buf==0xfe)
loc_tran17 6:e8f34b496ab0 262 {
loc_tran17 6:e8f34b496ab0 263 //Re-send auth using 4.0- auth
loc_tran17 6:e8f34b496ab0 264 sendAuth323();
loc_tran17 6:e8f34b496ab0 265 return;
loc_tran17 6:e8f34b496ab0 266 }
loc_tran17 6:e8f34b496ab0 267 m_watchdog.stop(); //Stop timeout
loc_tran17 6:e8f34b496ab0 268 m_watchdog.reset();
loc_tran17 6:e8f34b496ab0 269 if(m_len<2)
loc_tran17 6:e8f34b496ab0 270 {
loc_tran17 6:e8f34b496ab0 271 printf("Response too short..\n");
loc_tran17 6:e8f34b496ab0 272 onResult(MYSQL_PRTCL);
loc_tran17 6:e8f34b496ab0 273 return;
loc_tran17 6:e8f34b496ab0 274 }
loc_tran17 6:e8f34b496ab0 275 printf("RC=%d ",m_buf[0]);
loc_tran17 6:e8f34b496ab0 276 if(m_buf[0]==0)
loc_tran17 6:e8f34b496ab0 277 {
loc_tran17 6:e8f34b496ab0 278 m_buf[m_len] = 0;
loc_tran17 6:e8f34b496ab0 279 m_pPos = m_buf + 1;
loc_tran17 6:e8f34b496ab0 280 m_pPos += m_buf[1] +1;
loc_tran17 6:e8f34b496ab0 281 m_pPos += m_pPos[0];
loc_tran17 6:e8f34b496ab0 282 m_pPos += 1;
loc_tran17 6:e8f34b496ab0 283 printf("(OK) : Server status %d, Message : %s\n", *((uint16_t*)&m_pPos[0]), m_pPos+4);
loc_tran17 6:e8f34b496ab0 284 onResult(MYSQL_OK);
loc_tran17 6:e8f34b496ab0 285 }
loc_tran17 6:e8f34b496ab0 286 else
loc_tran17 6:e8f34b496ab0 287 {
loc_tran17 6:e8f34b496ab0 288 m_buf[m_len] = 0;
loc_tran17 6:e8f34b496ab0 289 printf("(Error %d) : %s\n", *((uint16_t*)&m_buf[1]), &m_buf[9]); //LE
loc_tran17 6:e8f34b496ab0 290 onResult(MYSQL_AUTHFAILED);
loc_tran17 6:e8f34b496ab0 291 return;
loc_tran17 6:e8f34b496ab0 292 }
loc_tran17 6:e8f34b496ab0 293 m_state = MYSQL_COMMANDS;
loc_tran17 6:e8f34b496ab0 294 }
loc_tran17 6:e8f34b496ab0 295
loc_tran17 6:e8f34b496ab0 296 void MySQLClient::sendAuth323()
loc_tran17 6:e8f34b496ab0 297 {
loc_tran17 6:e8f34b496ab0 298 printf("Using auth 4.0-\n");
loc_tran17 6:e8f34b496ab0 299 byte scramble[8]={0};
loc_tran17 6:e8f34b496ab0 300
loc_tran17 6:e8f34b496ab0 301 memcpy(scramble, &m_buf[BUF_SIZE-8], 8); //Recover scramble
loc_tran17 6:e8f34b496ab0 302
loc_tran17 6:e8f34b496ab0 303 //memcpy(scramble+8, m_pPos+31, 12); // *(m_pPos+43) == 0 (zero-terminated char*)
loc_tran17 6:e8f34b496ab0 304
loc_tran17 6:e8f34b496ab0 305 byte token[9]={0};
loc_tran17 6:e8f34b496ab0 306
loc_tran17 6:e8f34b496ab0 307 scramble_323((char*)token, (const char*)scramble, m_password.c_str());
loc_tran17 6:e8f34b496ab0 308
loc_tran17 6:e8f34b496ab0 309 printf("Building response\n");
loc_tran17 6:e8f34b496ab0 310 //Build response
loc_tran17 6:e8f34b496ab0 311
loc_tran17 6:e8f34b496ab0 312 memcpy((char*)m_buf,token,9);
loc_tran17 6:e8f34b496ab0 313 m_len = 9;
loc_tran17 6:e8f34b496ab0 314
loc_tran17 8:cdb6d1236f37 315 #if 0
loc_tran17 6:e8f34b496ab0 316 *((uint32_t*)&m_buf[0]) = htonl(clientFlags);
loc_tran17 6:e8f34b496ab0 317 *((uint32_t*)&m_buf[4]) = BUF_SIZE; //Max packets size
loc_tran17 6:e8f34b496ab0 318 m_buf[8] = 8; //latin1 charset
loc_tran17 6:e8f34b496ab0 319 memset((char*)(m_buf+9),0,23);
loc_tran17 6:e8f34b496ab0 320 strcpy((char*)(m_buf+32),m_user.c_str());
loc_tran17 6:e8f34b496ab0 321 m_pPos = m_buf + 32 + m_user.length() + 1;
loc_tran17 6:e8f34b496ab0 322 m_pPos[0] = 8;
loc_tran17 6:e8f34b496ab0 323 memcpy((char*)&m_pPos[1],token+1,8);
loc_tran17 6:e8f34b496ab0 324 strcpy((char*)(m_pPos+9),m_db.c_str());
loc_tran17 6:e8f34b496ab0 325 m_len = 32 + m_user.length() + 1 + 9 + m_db.length() + 1;
loc_tran17 8:cdb6d1236f37 326 #endif
loc_tran17 6:e8f34b496ab0 327
loc_tran17 6:e8f34b496ab0 328 printf("Writing data\n");
loc_tran17 6:e8f34b496ab0 329 writeData();
loc_tran17 6:e8f34b496ab0 330 }
loc_tran17 6:e8f34b496ab0 331
loc_tran17 6:e8f34b496ab0 332 void MySQLClient::sendCommand(byte command, byte* arg, int len)
loc_tran17 6:e8f34b496ab0 333 {
loc_tran17 6:e8f34b496ab0 334 printf("Sending command %d, payload of len %d\n", command, len);
loc_tran17 6:e8f34b496ab0 335 m_packetId=0;//Reset packet ID (New sequence)
loc_tran17 6:e8f34b496ab0 336 m_buf[0] = command;
loc_tran17 6:e8f34b496ab0 337 memcpy(&m_buf[1], arg, len);
loc_tran17 6:e8f34b496ab0 338 m_len = 1 + len;
loc_tran17 6:e8f34b496ab0 339 writeData();
loc_tran17 6:e8f34b496ab0 340 m_watchdog.start();
loc_tran17 6:e8f34b496ab0 341 }
loc_tran17 6:e8f34b496ab0 342
loc_tran17 6:e8f34b496ab0 343 void MySQLClient::handleCommandResult()
loc_tran17 6:e8f34b496ab0 344 {
loc_tran17 6:e8f34b496ab0 345 readData();
loc_tran17 6:e8f34b496ab0 346 m_watchdog.stop(); //Stop timeout
loc_tran17 6:e8f34b496ab0 347 m_watchdog.reset();
loc_tran17 6:e8f34b496ab0 348 if(m_len<2)
loc_tran17 6:e8f34b496ab0 349 {
loc_tran17 6:e8f34b496ab0 350 printf("Response too short..\n");
loc_tran17 6:e8f34b496ab0 351 onResult(MYSQL_PRTCL);
loc_tran17 6:e8f34b496ab0 352 return;
loc_tran17 6:e8f34b496ab0 353 }
loc_tran17 6:e8f34b496ab0 354 printf("RC=%d ",m_buf[0]);
loc_tran17 6:e8f34b496ab0 355 if(m_buf[0]==0)
loc_tran17 6:e8f34b496ab0 356 {
loc_tran17 6:e8f34b496ab0 357 printf("(OK)\n");
loc_tran17 6:e8f34b496ab0 358 onResult(MYSQL_OK);
loc_tran17 6:e8f34b496ab0 359 }
loc_tran17 6:e8f34b496ab0 360 else
loc_tran17 6:e8f34b496ab0 361 {
loc_tran17 6:e8f34b496ab0 362 m_buf[m_len] = 0;
loc_tran17 6:e8f34b496ab0 363 printf("(SQL Error %d) : %s\n", *((uint16_t*)&m_buf[1]), &m_buf[9]); //LE
loc_tran17 6:e8f34b496ab0 364 onResult(MYSQL_SQL);
loc_tran17 6:e8f34b496ab0 365 return;
loc_tran17 6:e8f34b496ab0 366 }
loc_tran17 6:e8f34b496ab0 367 }
loc_tran17 6:e8f34b496ab0 368
loc_tran17 6:e8f34b496ab0 369 void MySQLClient::readData() //Copy to buf
loc_tran17 6:e8f34b496ab0 370 {
loc_tran17 6:e8f34b496ab0 371 byte head[4];
loc_tran17 6:e8f34b496ab0 372 int ret = m_pTCPSocket->receive((char*)head, 4); //Packet header
loc_tran17 6:e8f34b496ab0 373 m_len = *((uint16_t*)&head[0]);
loc_tran17 6:e8f34b496ab0 374 m_packetId = head[3];
loc_tran17 6:e8f34b496ab0 375 printf("Packet Id %d of length %d\n", head[3], m_len);
loc_tran17 6:e8f34b496ab0 376 m_packetId++;
loc_tran17 6:e8f34b496ab0 377 if(ret>0)
loc_tran17 6:e8f34b496ab0 378 ret = m_pTCPSocket->receive((char*)m_buf, m_len);
loc_tran17 6:e8f34b496ab0 379 if(ret < 0)//Error
loc_tran17 6:e8f34b496ab0 380 {
loc_tran17 6:e8f34b496ab0 381 onResult(MYSQL_CONN);
loc_tran17 6:e8f34b496ab0 382 return;
loc_tran17 6:e8f34b496ab0 383 }
loc_tran17 6:e8f34b496ab0 384 if(ret < m_len)
loc_tran17 6:e8f34b496ab0 385 {
loc_tran17 6:e8f34b496ab0 386 printf("WARN: Incomplete packet\n");
loc_tran17 6:e8f34b496ab0 387 }
loc_tran17 6:e8f34b496ab0 388 m_len = ret;
loc_tran17 6:e8f34b496ab0 389 }
loc_tran17 6:e8f34b496ab0 390
loc_tran17 6:e8f34b496ab0 391 void MySQLClient::writeData() //Copy from buf
loc_tran17 6:e8f34b496ab0 392 {
loc_tran17 6:e8f34b496ab0 393 byte head[4] = { 0 };
loc_tran17 6:e8f34b496ab0 394 *((uint16_t*)&head[0]) = m_len;
loc_tran17 6:e8f34b496ab0 395 head[3] = m_packetId;
loc_tran17 6:e8f34b496ab0 396 printf("Packet Id %d\n", head[3]);
loc_tran17 6:e8f34b496ab0 397 m_packetId++;
loc_tran17 6:e8f34b496ab0 398 int ret = m_pTCPSocket->send((char*)head, 4); //Packet header
loc_tran17 6:e8f34b496ab0 399 if(ret>0)
loc_tran17 6:e8f34b496ab0 400 ret = m_pTCPSocket->send((char*)m_buf, m_len);
loc_tran17 6:e8f34b496ab0 401 if(ret < 0)//Error
loc_tran17 6:e8f34b496ab0 402 {
loc_tran17 6:e8f34b496ab0 403 onResult(MYSQL_CONN);
loc_tran17 6:e8f34b496ab0 404 return;
loc_tran17 6:e8f34b496ab0 405 }
loc_tran17 6:e8f34b496ab0 406 m_len = 0;//FIXME... incomplete packets handling
loc_tran17 6:e8f34b496ab0 407 }
loc_tran17 6:e8f34b496ab0 408
loc_tran17 6:e8f34b496ab0 409
loc_tran17 6:e8f34b496ab0 410 void MySQLClient::onResult(MySQLResult r) //Called when exchange completed or on failure
loc_tran17 6:e8f34b496ab0 411 {
loc_tran17 6:e8f34b496ab0 412 if(m_pCbItem && m_pCbMeth)
loc_tran17 6:e8f34b496ab0 413 (m_pCbItem->*m_pCbMeth)(r);
loc_tran17 6:e8f34b496ab0 414 else if(m_pCb)
loc_tran17 6:e8f34b496ab0 415 m_pCb(r);
loc_tran17 6:e8f34b496ab0 416
loc_tran17 6:e8f34b496ab0 417 if( (r==MYSQL_DNS) || (r==MYSQL_PRTCL) || (r==MYSQL_AUTHFAILED) || (r==MYSQL_TIMEOUT) || (r==MYSQL_CONN) ) //Fatal error, close connection
loc_tran17 6:e8f34b496ab0 418 close();
loc_tran17 6:e8f34b496ab0 419 }
loc_tran17 6:e8f34b496ab0 420
loc_tran17 6:e8f34b496ab0 421 void MySQLClient::onTimeout() //Connection has timed out
loc_tran17 6:e8f34b496ab0 422 {
loc_tran17 6:e8f34b496ab0 423 printf("Timed out.\n");
loc_tran17 6:e8f34b496ab0 424 onResult(MYSQL_TIMEOUT);
loc_tran17 6:e8f34b496ab0 425 close();
loc_tran17 6:e8f34b496ab0 426 }
loc_tran17 6:e8f34b496ab0 427
loc_tran17 6:e8f34b496ab0 428
loc_tran17 6:e8f34b496ab0 429
loc_tran17 6:e8f34b496ab0 430