Signup and login now working! All new improved packet creation/parsing code - no more wasteful structures!
This commit is contained in:
parent
ba1fe40938
commit
4cb64344be
10 changed files with 272 additions and 108 deletions
|
@ -45,10 +45,12 @@ static ButtonT *_btnLogin = NULL;
|
||||||
|
|
||||||
static void btnCancelClick(WidgetT *widget);
|
static void btnCancelClick(WidgetT *widget);
|
||||||
static void btnSignUpClick(WidgetT *widget);
|
static void btnSignUpClick(WidgetT *widget);
|
||||||
static void btnLoginClick(WidgetT *widget);
|
|
||||||
static void btnMsgBoxCancel(MsgBoxButtonT button);
|
static void btnMsgBoxCancel(MsgBoxButtonT button);
|
||||||
|
static void btnMsgBoxContinue(MsgBoxButtonT button);
|
||||||
|
static void btnMsgBoxFinish(MsgBoxButtonT button);
|
||||||
static void setButtons(uint8_t enabled);
|
static void setButtons(uint8_t enabled);
|
||||||
static void taskDisconnect(void *data);
|
static void taskDisconnect(void *data);
|
||||||
|
static void taskLoginClick(void *data);
|
||||||
|
|
||||||
|
|
||||||
static void btnCancelClick(WidgetT *widget) {
|
static void btnCancelClick(WidgetT *widget) {
|
||||||
|
@ -69,12 +71,6 @@ static void btnSignUpClick(WidgetT *widget) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void btnLoginClick(WidgetT *widget) {
|
|
||||||
(void)widget;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void btnMsgBoxCancel(MsgBoxButtonT button) {
|
static void btnMsgBoxCancel(MsgBoxButtonT button) {
|
||||||
|
|
||||||
if (button == MSGBOX_BUTTON_ONE) {
|
if (button == MSGBOX_BUTTON_ONE) {
|
||||||
|
@ -86,6 +82,13 @@ static void btnMsgBoxCancel(MsgBoxButtonT button) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void btnMsgBoxContinue(MsgBoxButtonT button) {
|
||||||
|
(void)button;
|
||||||
|
|
||||||
|
setButtons(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setButtons(uint8_t enabled) {
|
static void setButtons(uint8_t enabled) {
|
||||||
widgetEnableSet(W(_btnCancel), enabled);
|
widgetEnableSet(W(_btnCancel), enabled);
|
||||||
widgetEnableSet(W(_btnSignUp), enabled);
|
widgetEnableSet(W(_btnSignUp), enabled);
|
||||||
|
@ -122,6 +125,8 @@ void taskLogin(void *data) {
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
|
||||||
|
// ***TODO*** We used to have a FORGOT PASSWORD button here, too.
|
||||||
|
|
||||||
TagItemT uiLogin[] = {
|
TagItemT uiLogin[] = {
|
||||||
T_START,
|
T_START,
|
||||||
T_WINDOW, O(_winLogin),
|
T_WINDOW, O(_winLogin),
|
||||||
|
@ -156,7 +161,8 @@ void taskLogin(void *data) {
|
||||||
T_BUTTON, O(_btnLogin),
|
T_BUTTON, O(_btnLogin),
|
||||||
T_TITLE, P("Login"),
|
T_TITLE, P("Login"),
|
||||||
T_X, 199, T_Y, 85,
|
T_X, 199, T_Y, 85,
|
||||||
T_CLICK, P(btnLoginClick),
|
T_CLICK, P(taskProxy),
|
||||||
|
T_USER_DATA, P(taskLoginClick),
|
||||||
T_BUTTON, T_DONE,
|
T_BUTTON, T_DONE,
|
||||||
|
|
||||||
T_WINDOW, T_DONE,
|
T_WINDOW, T_DONE,
|
||||||
|
@ -165,3 +171,61 @@ void taskLogin(void *data) {
|
||||||
|
|
||||||
tagListRun(uiLogin);
|
tagListRun(uiLogin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void taskLoginClick(void *data) {
|
||||||
|
char *packetData = NULL;
|
||||||
|
int8_t success = 0;
|
||||||
|
uint16_t length = 0;
|
||||||
|
int16_t timeout = 10;
|
||||||
|
PacketEncodeDataT encoded = { 0 };
|
||||||
|
PacketDecodeDataT *decoded = NULL;
|
||||||
|
|
||||||
|
(void)data;
|
||||||
|
|
||||||
|
// ***TODO*** This should disable the entire dialog instead of just the buttons. Need to finish the Enable GUI code first.
|
||||||
|
|
||||||
|
setButtons(0);
|
||||||
|
|
||||||
|
packetData = packetContentPack(&length, "ss", textboxValueGet(_txtUser), textboxValueGet(_txtPass));
|
||||||
|
|
||||||
|
// Send login request.
|
||||||
|
encoded.packetType = PACKET_TYPE_LOGIN;
|
||||||
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
|
encoded.channel = 0;
|
||||||
|
encoded.encrypt = 1;
|
||||||
|
packetEncode(__packetThreadData, &encoded, packetData, length);
|
||||||
|
packetSend(__packetThreadData, &encoded);
|
||||||
|
|
||||||
|
DEL(packetData);
|
||||||
|
|
||||||
|
// Wait for response.
|
||||||
|
do {
|
||||||
|
decoded = netGetPacket(0);
|
||||||
|
if (decoded) {
|
||||||
|
switch (decoded->packetType) {
|
||||||
|
case PACKET_TYPE_LOGIN_RESULT:
|
||||||
|
packetContentUnpack(decoded->data, "is", &success, &packetData);
|
||||||
|
logWrite("Login: %d %s\n", success, packetData);
|
||||||
|
if (success) {
|
||||||
|
// ***TODO*** Start Main Menu
|
||||||
|
guiDelete(D(_winLogin));
|
||||||
|
// taskCreate(taskLogin, NULL);
|
||||||
|
} else {
|
||||||
|
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, packetData, "Okay", btnMsgBoxContinue);
|
||||||
|
}
|
||||||
|
DEL(packetData);
|
||||||
|
timeout = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, "Unexpected packet received.", "Okay", btnMsgBoxContinue);
|
||||||
|
timeout = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
packetDecodeDataDestroy(&decoded);
|
||||||
|
}
|
||||||
|
taskYield();
|
||||||
|
if (__timerQuarterSecondTick) timeout--;
|
||||||
|
} while (!guiHasStopped() && timeout > 0);
|
||||||
|
}
|
||||||
|
|
|
@ -175,9 +175,9 @@ void taskSignUp(void *data) {
|
||||||
static void taskSignUpClick(void *data) {
|
static void taskSignUpClick(void *data) {
|
||||||
PacketEncodeDataT encoded = { 0 };
|
PacketEncodeDataT encoded = { 0 };
|
||||||
PacketDecodeDataT *decoded = NULL;
|
PacketDecodeDataT *decoded = NULL;
|
||||||
PacketTypeSignUpT signup = { 0 };
|
int16_t timeout = 10;
|
||||||
PacketTypeSignUpResultT *result = { 0 };
|
uint16_t length = 0;
|
||||||
int16_t timeout = 5;
|
char *packetData = NULL;
|
||||||
|
|
||||||
(void)data;
|
(void)data;
|
||||||
|
|
||||||
|
@ -185,23 +185,16 @@ static void taskSignUpClick(void *data) {
|
||||||
|
|
||||||
setButtons(0);
|
setButtons(0);
|
||||||
|
|
||||||
// Get the data.
|
|
||||||
memcpy(signup.email, textboxValueGet(_txtEmail), strlen(textboxValueGet(_txtEmail)));
|
|
||||||
memcpy(signup.first, textboxValueGet(_txtFirst), strlen(textboxValueGet(_txtFirst)));
|
|
||||||
memcpy(signup.last, textboxValueGet(_txtLast), strlen(textboxValueGet(_txtLast)));
|
|
||||||
memcpy(signup.pass, textboxValueGet(_txtPass1), strlen(textboxValueGet(_txtPass1)));
|
|
||||||
memcpy(signup.user, textboxValueGet(_txtUser), strlen(textboxValueGet(_txtUser)));
|
|
||||||
|
|
||||||
// Validate it. ***TODO*** These messages could be a lot better.
|
// Validate it. ***TODO*** These messages could be a lot better.
|
||||||
if (!validateEmail(signup.email)) {
|
if (!validateEmail(textboxValueGet(_txtEmail))) {
|
||||||
msgBoxOne("Invalid E-Mail", MSGBOX_ICON_ERROR, "Please enter a valid E-mail address.", "Okay", btnMsgBoxContinue);
|
msgBoxOne("Invalid E-Mail", MSGBOX_ICON_ERROR, "Please enter a valid E-mail address.", "Okay", btnMsgBoxContinue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!validateName(signup.first)) {
|
if (!validateName(textboxValueGet(_txtFirst))) {
|
||||||
msgBoxOne("Invalid First Name", MSGBOX_ICON_ERROR, "Please enter a valid first name.", "Okay", btnMsgBoxContinue);
|
msgBoxOne("Invalid First Name", MSGBOX_ICON_ERROR, "Please enter a valid first name.", "Okay", btnMsgBoxContinue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!validateName(signup.last)) {
|
if (!validateName(textboxValueGet(_txtLast))) {
|
||||||
msgBoxOne("Invalid Last Name", MSGBOX_ICON_ERROR, "Please enter a valid last name.", "Okay", btnMsgBoxContinue);
|
msgBoxOne("Invalid Last Name", MSGBOX_ICON_ERROR, "Please enter a valid last name.", "Okay", btnMsgBoxContinue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -209,40 +202,52 @@ static void taskSignUpClick(void *data) {
|
||||||
msgBoxOne("Invalid Password", MSGBOX_ICON_ERROR, "Passwords must match.", "Okay", btnMsgBoxContinue);
|
msgBoxOne("Invalid Password", MSGBOX_ICON_ERROR, "Passwords must match.", "Okay", btnMsgBoxContinue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!validatePassword(signup.pass)) {
|
if (!validatePassword(textboxValueGet(_txtPass1))) {
|
||||||
msgBoxOne("Invalid Password", MSGBOX_ICON_ERROR, "Please enter a valid password.", "Okay", btnMsgBoxContinue);
|
msgBoxOne("Invalid Password", MSGBOX_ICON_ERROR, "Please enter a valid password.", "Okay", btnMsgBoxContinue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!validateUser(signup.user)) {
|
if (!validateUser(textboxValueGet(_txtUser))) {
|
||||||
msgBoxOne("Invalid User Name", MSGBOX_ICON_ERROR, "Please enter a valid user name.", "Okay", btnMsgBoxContinue);
|
msgBoxOne("Invalid User Name", MSGBOX_ICON_ERROR, "Please enter a valid user name.", "Okay", btnMsgBoxContinue);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
packetData = packetContentPack(&length, "sssss",
|
||||||
|
textboxValueGet(_txtEmail),
|
||||||
|
textboxValueGet(_txtFirst),
|
||||||
|
textboxValueGet(_txtLast),
|
||||||
|
textboxValueGet(_txtPass1),
|
||||||
|
textboxValueGet(_txtUser)
|
||||||
|
);
|
||||||
|
|
||||||
// Send signup request.
|
// Send signup request.
|
||||||
encoded.packetType = PACKET_TYPE_SIGNUP;
|
encoded.packetType = PACKET_TYPE_SIGNUP;
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
encoded.channel = 0;
|
encoded.channel = 0;
|
||||||
encoded.encrypt = 0;
|
encoded.encrypt = 1;
|
||||||
packetEncode(__packetThreadData, &encoded, (char *)&signup, sizeof(PacketTypeSignUpT));
|
packetEncode(__packetThreadData, &encoded, packetData, length);
|
||||||
packetSend(__packetThreadData, &encoded);
|
packetSend(__packetThreadData, &encoded);
|
||||||
|
|
||||||
|
DEL(packetData);
|
||||||
|
|
||||||
// Wait for response.
|
// Wait for response.
|
||||||
do {
|
do {
|
||||||
decoded = netGetPacket(0);
|
decoded = netGetPacket(0);
|
||||||
if (decoded) {
|
if (decoded) {
|
||||||
switch (decoded->packetType) {
|
switch (decoded->packetType) {
|
||||||
case PACKET_TYPE_SIGNUP_RESULT:
|
case PACKET_TYPE_SIGNUP_RESULT:
|
||||||
result = (PacketTypeSignUpResultT *)decoded->data;
|
packetContentUnpack(decoded->data, "is", &length, &packetData);
|
||||||
if (result->success) {
|
if (length) {
|
||||||
msgBoxOne("Success!", MSGBOX_ICON_INFORMATION, result->message, "Okay", btnMsgBoxFinish);
|
msgBoxOne("Success!", MSGBOX_ICON_INFORMATION, packetData, "Okay", btnMsgBoxFinish);
|
||||||
} else {
|
} else {
|
||||||
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, result->message, "Okay", btnMsgBoxContinue);
|
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, packetData, "Okay", btnMsgBoxContinue);
|
||||||
}
|
}
|
||||||
|
DEL(packetData);
|
||||||
timeout = 0;
|
timeout = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logWrite("Unexpected packet received: %d\n", decoded->packetType);
|
msgBoxOne("Uh Oh!", MSGBOX_ICON_ERROR, "Unexpected packet received.", "Okay", btnMsgBoxContinue);
|
||||||
|
timeout = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
packetDecodeDataDestroy(&decoded);
|
packetDecodeDataDestroy(&decoded);
|
||||||
|
@ -250,8 +255,6 @@ static void taskSignUpClick(void *data) {
|
||||||
taskYield();
|
taskYield();
|
||||||
if (__timerQuarterSecondTick) timeout--;
|
if (__timerQuarterSecondTick) timeout--;
|
||||||
} while (!guiHasStopped() && timeout > 0);
|
} while (!guiHasStopped() && timeout > 0);
|
||||||
|
|
||||||
setButtons(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ static void taskConnectClick(void *data) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_TYPE_VERSION:
|
case PACKET_TYPE_VERSION:
|
||||||
__runtimeData.protocolVersion = *(uint32_t *)decoded->data;
|
packetContentUnpack(decoded->data, "i", &__runtimeData.protocolVersion);
|
||||||
// Do we need to update?
|
// Do we need to update?
|
||||||
if (PACKET_PROTOCOL_VERSION == __runtimeData.protocolVersion) {
|
if (PACKET_PROTOCOL_VERSION == __runtimeData.protocolVersion) {
|
||||||
// Nope, we're good.
|
// Nope, we're good.
|
||||||
|
|
|
@ -5,7 +5,6 @@ function kpApiUserCreate($first, $last, $username, $email, $password, &$response
|
||||||
// Check for duplicate username.
|
// Check for duplicate username.
|
||||||
$user = kirby()->users()->filterBy('name', $username);
|
$user = kirby()->users()->filterBy('name', $username);
|
||||||
if ($user->first()) {
|
if ($user->first()) {
|
||||||
$response['result'] = 'false';
|
|
||||||
$response['reason'] = 'User name already exists.';
|
$response['reason'] = 'User name already exists.';
|
||||||
} else {
|
} else {
|
||||||
// Save Kirby attributes.
|
// Save Kirby attributes.
|
||||||
|
@ -41,7 +40,7 @@ function kpApiUserCreate($first, $last, $username, $email, $password, &$response
|
||||||
|
|
||||||
// Return result.
|
// Return result.
|
||||||
$response['result'] = 'true';
|
$response['result'] = 'true';
|
||||||
$response['reason'] = 'User created. Check your E-mail for activation instructions.';
|
$response['reason'] = 'Check your E-mail for activation instructions.';
|
||||||
}
|
}
|
||||||
} catch(Exception $e) {
|
} catch(Exception $e) {
|
||||||
if (strpos($e->getMessage(), "email")) {
|
if (strpos($e->getMessage(), "email")) {
|
||||||
|
@ -53,23 +52,23 @@ function kpApiUserCreate($first, $last, $username, $email, $password, &$response
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function kpApiUserGet($email, &$response) {
|
function kpApiUserLogin($username, $pass, &$response) {
|
||||||
try {
|
try {
|
||||||
$user = kirby()->users()->findByKey($email);
|
// Find user by name instead of email.
|
||||||
//$response['userraw'] = dump($user);
|
$user = kirby()->users()->filterBy('name', $username)->first();
|
||||||
if ($user) {
|
if ($user) {
|
||||||
$response['name'] = $user->username();
|
// Attempt to sign them in.
|
||||||
$response['email'] = $user->email();
|
kirby()->auth()->login($user->email(), $pass);
|
||||||
$response['password'] = $user->password();
|
// They don't need an actual Kirby session, so log them off.
|
||||||
$response['language'] = $user->language();
|
kirby()->auth()->logout();
|
||||||
$response['role'] = $user->role()->id();
|
// Report it.
|
||||||
$response['result'] = 'true';
|
$response['result'] = 'true';
|
||||||
$response['reason'] = 'User found.';
|
$response['reason'] = 'User logged in.';
|
||||||
} else {
|
} else {
|
||||||
$response['reason'] = 'User not found.';
|
$response['reason'] = 'User name or password incorrect.';
|
||||||
}
|
}
|
||||||
} catch(Exception $e) {
|
} catch(Exception $e) {
|
||||||
$response['reason'] = $e->getMessage();
|
$response['reason'] = 'User name or password incorrect.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,8 +43,8 @@ return [
|
||||||
kpApiUserCreate(get('first'), get('last'), get('user'), get('email'), get('pass'), $response);
|
kpApiUserCreate(get('first'), get('last'), get('user'), get('email'), get('pass'), $response);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'USER_GET':
|
case 'USER_LOGIN':
|
||||||
kpApiUserGet(get('email'), $response);
|
kpApiUserLogin(get('user'), get('pass'), $response);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -67,16 +67,22 @@ static void clientProcessPacket(ClientThreadT *client, PacketDecodeDataT *data)
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
uint64_t x = 0;
|
uint64_t x = 0;
|
||||||
uint32_t y = 0;
|
uint32_t y = 0;
|
||||||
uint64_t length = 0;
|
uint16_t length = 0;
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
|
char *packetData = NULL;
|
||||||
|
char *user = NULL;
|
||||||
|
char *pass = NULL;
|
||||||
|
char *first = NULL;
|
||||||
|
char *last = NULL;
|
||||||
|
char *email = NULL;
|
||||||
PacketEncodeDataT encoded = { 0 };
|
PacketEncodeDataT encoded = { 0 };
|
||||||
json_object *response = NULL;
|
json_object *response = NULL;
|
||||||
RestStringMapT *strings = NULL;
|
RestStringMapT *strings = NULL;
|
||||||
RestIntegerMapT *integers = NULL;
|
RestIntegerMapT *integers = NULL;
|
||||||
struct timespec timer = { 0 };
|
struct timespec timer = { 0 };
|
||||||
double d = 0;
|
double d = 0;
|
||||||
PacketTypeSignUpT *signup = NULL;
|
uint8_t result = 0;
|
||||||
PacketTypeSignUpResultT signupResult = { 0 };
|
char *string = NULL;
|
||||||
|
|
||||||
switch (data->packetType) {
|
switch (data->packetType) {
|
||||||
case PACKET_TYPE_CLIENT_SHUTDOWN:
|
case PACKET_TYPE_CLIENT_SHUTDOWN:
|
||||||
|
@ -84,7 +90,34 @@ static void clientProcessPacket(ClientThreadT *client, PacketDecodeDataT *data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_TYPE_LOGIN:
|
case PACKET_TYPE_LOGIN:
|
||||||
consoleMessageQueue("%ld: Channel %d %s %s\n", client->threadIndex, data->channel, ((PacketTypeLoginT *)data->data)->user, ((PacketTypeLoginT *)data->data)->pass);
|
packetContentUnpack(data->data, "ss", &user, &pass);
|
||||||
|
response = restRequest("USER_LOGIN", "ss",
|
||||||
|
"user", user,
|
||||||
|
"pass", pass
|
||||||
|
);
|
||||||
|
DEL(user);
|
||||||
|
DEL(pass);
|
||||||
|
if (response) {
|
||||||
|
string = (char *)json_object_get_string(json_object_object_get(response, "result"));
|
||||||
|
result = (string[0] == 't' || string[0] == 'T') ? 1 : 0;
|
||||||
|
buffer = (char *)json_object_get_string(json_object_object_get(response, "reason"));
|
||||||
|
} else {
|
||||||
|
// Something bad happened.
|
||||||
|
result = 0;
|
||||||
|
buffer = "Unknown error. Sorry.";
|
||||||
|
}
|
||||||
|
logWrite("Login: %d %s\r\n", result, buffer);
|
||||||
|
packetData = packetContentPack(&length, "is", result, buffer);
|
||||||
|
if (response) restRelease(response);
|
||||||
|
// Build packet.
|
||||||
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
|
encoded.packetType = PACKET_TYPE_LOGIN_RESULT;
|
||||||
|
encoded.channel = 0;
|
||||||
|
encoded.encrypt = 0;
|
||||||
|
packetEncode(client->packetThreadData, &encoded, packetData, length);
|
||||||
|
// Send it.
|
||||||
|
packetSend(client->packetThreadData, &encoded);
|
||||||
|
DEL(packetData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_TYPE_PONG:
|
case PACKET_TYPE_PONG:
|
||||||
|
@ -111,32 +144,34 @@ static void clientProcessPacket(ClientThreadT *client, PacketDecodeDataT *data)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_TYPE_SIGNUP:
|
case PACKET_TYPE_SIGNUP:
|
||||||
signup = (PacketTypeSignUpT *)data->data;
|
packetContentUnpack(data->data, "sssss", &email, &first, &last, &pass, &user);
|
||||||
response = restRequest("USER_CREATE", "sssss",
|
response = restRequest("USER_CREATE", "sssss",
|
||||||
"first", signup->first,
|
"first", first,
|
||||||
"last", signup->last,
|
"last", last,
|
||||||
"user", signup->user,
|
"user", user,
|
||||||
"pass", signup->pass,
|
"pass", pass,
|
||||||
"email", signup->email
|
"email", email
|
||||||
);
|
);
|
||||||
if (response) {
|
if (response) {
|
||||||
signupResult.success = (json_object_get_boolean(json_object_object_get(response, "result")) == TRUE) ? 1 : 0;
|
string = (char *)json_object_get_string(json_object_object_get(response, "result"));
|
||||||
|
result = (string[0] == 't' || string[0] == 'T') ? 1 : 0;
|
||||||
buffer = (char *)json_object_get_string(json_object_object_get(response, "reason"));
|
buffer = (char *)json_object_get_string(json_object_object_get(response, "reason"));
|
||||||
} else {
|
} else {
|
||||||
// Something bad happened.
|
// Something bad happened.
|
||||||
signupResult.success = 0;
|
result = 0;
|
||||||
buffer = "Unknown error. Sorry.";
|
buffer = "Unknown error. Sorry.";
|
||||||
}
|
}
|
||||||
memcpy(signupResult.message, buffer, strlen(buffer));
|
packetData = packetContentPack(&length, "is", result, buffer);
|
||||||
if (response) restRelease(response);
|
if (response) restRelease(response);
|
||||||
// Build packet.
|
// Build packet.
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
encoded.packetType = PACKET_TYPE_SIGNUP_RESULT;
|
encoded.packetType = PACKET_TYPE_SIGNUP_RESULT;
|
||||||
encoded.channel = 0;
|
encoded.channel = 0;
|
||||||
encoded.encrypt = 0;
|
encoded.encrypt = 0;
|
||||||
packetEncode(client->packetThreadData, &encoded, (char *)&signupResult, sizeof(PacketTypeSignUpResultT));
|
packetEncode(client->packetThreadData, &encoded, packetData, length);
|
||||||
// Send it.
|
// Send it.
|
||||||
packetSend(client->packetThreadData, &encoded);
|
packetSend(client->packetThreadData, &encoded);
|
||||||
|
DEL(packetData);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PACKET_TYPE_VERSION_BAD:
|
case PACKET_TYPE_VERSION_BAD:
|
||||||
|
@ -269,11 +304,12 @@ void *clientThread(void *data) {
|
||||||
PacketEncodeDataT encoded = { 0 };
|
PacketEncodeDataT encoded = { 0 };
|
||||||
struct timespec remaining = { 0, 0 };
|
struct timespec remaining = { 0, 0 };
|
||||||
struct timespec sleepTime = { 0, 1000000000/100 }; // 1/100th second.
|
struct timespec sleepTime = { 0, 1000000000/100 }; // 1/100th second.
|
||||||
PacketTypeVersionT version = { 0 };
|
|
||||||
uint8_t versionSent = 0;
|
uint8_t versionSent = 0;
|
||||||
time_t ticks = { 0 };
|
time_t ticks = { 0 };
|
||||||
time_t lastTicks = { 0 };
|
time_t lastTicks = { 0 };
|
||||||
int8_t pingTimeout = 0;
|
int8_t pingTimeout = 0;
|
||||||
|
char *packetData = NULL;
|
||||||
|
uint16_t length = 0;
|
||||||
|
|
||||||
// Process packets until we're done.
|
// Process packets until we're done.
|
||||||
while (client->running) {
|
while (client->running) {
|
||||||
|
@ -282,14 +318,15 @@ void *clientThread(void *data) {
|
||||||
// Start communications with client as soon as encryption channel is ready.
|
// Start communications with client as soon as encryption channel is ready.
|
||||||
if (!versionSent) {
|
if (!versionSent) {
|
||||||
if (packetEncryptionReady()) {
|
if (packetEncryptionReady()) {
|
||||||
|
packetData = packetContentPack(&length, "i", PACKET_PROTOCOL_VERSION);
|
||||||
// Send required protocol version.
|
// Send required protocol version.
|
||||||
version.version = PACKET_PROTOCOL_VERSION;
|
|
||||||
encoded.control = PACKET_CONTROL_DAT;
|
encoded.control = PACKET_CONTROL_DAT;
|
||||||
encoded.packetType = PACKET_TYPE_VERSION;
|
encoded.packetType = PACKET_TYPE_VERSION;
|
||||||
encoded.channel = 0;
|
encoded.channel = 0;
|
||||||
encoded.encrypt = 0;
|
encoded.encrypt = 0;
|
||||||
packetEncode(client->packetThreadData, &encoded, (char *)&version, sizeof(PacketTypeVersionT));
|
packetEncode(client->packetThreadData, &encoded, packetData, length);
|
||||||
packetSend(client->packetThreadData, &encoded);
|
packetSend(client->packetThreadData, &encoded);
|
||||||
|
DEL(packetData);
|
||||||
versionSent = 1;
|
versionSent = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,7 +342,7 @@ void *clientThread(void *data) {
|
||||||
encoded.packetType = PACKET_TYPE_PING;
|
encoded.packetType = PACKET_TYPE_PING;
|
||||||
encoded.channel = 0;
|
encoded.channel = 0;
|
||||||
encoded.encrypt = 0;
|
encoded.encrypt = 0;
|
||||||
packetEncode(client->packetThreadData, &encoded, (char *)&version, sizeof(PacketTypeVersionT));
|
packetEncode(client->packetThreadData, &encoded, NULL, 0);
|
||||||
packetSend(client->packetThreadData, &encoded);
|
packetSend(client->packetThreadData, &encoded);
|
||||||
clock_gettime(CLOCK_MONOTONIC_RAW, &client->pingStart);
|
clock_gettime(CLOCK_MONOTONIC_RAW, &client->pingStart);
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,22 +187,26 @@ void restRelease(json_object *object) {
|
||||||
|
|
||||||
|
|
||||||
json_object *restRequest(char *command, char *format, ...) {
|
json_object *restRequest(char *command, char *format, ...) {
|
||||||
va_list args = { 0 };
|
va_list args = { 0 };
|
||||||
json_object *request = json_object_new_object();
|
json_object *request = json_object_new_object();
|
||||||
json_object *response = NULL;
|
json_object *response = NULL;
|
||||||
|
char *key = NULL;
|
||||||
|
char *string = NULL;
|
||||||
|
uint8_t result = 0;
|
||||||
|
|
||||||
json_object_object_add(request, "command", json_object_new_string(command));
|
json_object_object_add(request, "command", json_object_new_string(command));
|
||||||
|
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
if (format) {
|
if (format) {
|
||||||
while (*format != 0) {
|
while (*format != 0) {
|
||||||
|
key = va_arg(args, char *);
|
||||||
switch (*format) {
|
switch (*format) {
|
||||||
case 's':
|
case 's':
|
||||||
json_object_object_add(request, va_arg(args, char *), json_object_new_string(va_arg(args, char *)));
|
json_object_object_add(request, key, json_object_new_string(va_arg(args, char *)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
json_object_object_add(request, va_arg(args, char *), json_object_new_int64(va_arg(args, int64_t)));
|
json_object_object_add(request, key, json_object_new_int64(va_arg(args, int64_t)));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -217,10 +221,12 @@ json_object *restRequest(char *command, char *format, ...) {
|
||||||
//logWrite("Request: %s\n", json_object_to_json_string_ext(request, JSON_C_TO_STRING_PRETTY));
|
//logWrite("Request: %s\n", json_object_to_json_string_ext(request, JSON_C_TO_STRING_PRETTY));
|
||||||
response = restUrlPost(request);
|
response = restUrlPost(request);
|
||||||
json_object_put(request);
|
json_object_put(request);
|
||||||
//logWrite("Response: %s\n", json_object_to_json_string_ext(response, JSON_C_TO_STRING_PRETTY));
|
logWrite("Response: %s\n", json_object_to_json_string_ext(response, JSON_C_TO_STRING_PRETTY));
|
||||||
|
|
||||||
if (response) {
|
if (response) {
|
||||||
if (json_object_get_boolean(json_object_object_get(response, "result")) != TRUE) {
|
string = (char *)json_object_get_string(json_object_object_get(response, "result"));
|
||||||
|
result = (string[0] == 't' || string[0] == 'T') ? 1 : 0;
|
||||||
|
if (result) {
|
||||||
logWrite("restRequest: %s\n", json_object_get_string(json_object_object_get(response, "reason")));
|
logWrite("restRequest: %s\n", json_object_get_string(json_object_object_get(response, "reason")));
|
||||||
json_object_put(response);
|
json_object_put(response);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
#include "packet.h"
|
#include "packet.h"
|
||||||
#include "primes.h"
|
#include "primes.h"
|
||||||
|
|
||||||
|
@ -71,6 +73,89 @@ static void *packetAesContextCreate(uint8_t *key, uint8_t *iv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *packetContentPack(uint16_t *length, char *format, ...) {
|
||||||
|
va_list args = { 0 };
|
||||||
|
static char work[PACKET_MAX] = { 0 };
|
||||||
|
char *result = NULL;
|
||||||
|
char *buffer = NULL;
|
||||||
|
int8_t value8 = 0;
|
||||||
|
int32_t value32 = 0;
|
||||||
|
|
||||||
|
*length = 0;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
if (format) {
|
||||||
|
while (*format != 0) {
|
||||||
|
switch (*format) {
|
||||||
|
case 'i':
|
||||||
|
// Copy integer as 32-bit integer.
|
||||||
|
value32 = va_arg(args, int32_t);
|
||||||
|
memcpy(&work[*length], &value32, sizeof(int32_t));
|
||||||
|
*length += sizeof(int32_t);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
// Copy string including the terminating zero.
|
||||||
|
buffer = va_arg(args, char *);
|
||||||
|
memcpy(&work[*length], buffer, strlen(buffer) + 1);
|
||||||
|
*length += strlen(buffer) + 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
utilDie("restRequest: Unknown format option '%c'.\n", *format);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
// Copy working buffer to result to return.
|
||||||
|
if (*length > 0) {
|
||||||
|
result = (char *)malloc(*length);
|
||||||
|
memcpy(result, work, *length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void packetContentUnpack(char *buffer, char *format, ...) {
|
||||||
|
va_list args = { 0 };
|
||||||
|
char **string = NULL;
|
||||||
|
int8_t *value8 = NULL;
|
||||||
|
int32_t *value32 = NULL;
|
||||||
|
uint16_t length = 0;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
if (format) {
|
||||||
|
while (*format != 0) {
|
||||||
|
switch (*format) {
|
||||||
|
case 'i':
|
||||||
|
// Copy integer as 32-bit integer.
|
||||||
|
value32 = va_arg(args, int32_t *);
|
||||||
|
memcpy(value32, &buffer[length], sizeof(int32_t));
|
||||||
|
length += sizeof(int32_t);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
// Copy string including the terminating zero.
|
||||||
|
string = va_arg(args, char **);
|
||||||
|
*string = strdup(&buffer[length]);
|
||||||
|
length += strlen(*string) + 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
utilDie("restRequest: Unknown format option '%c'.\n", *format);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
format++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint8_t packetCRC(char *data, uint16_t length, uint8_t startAt) {
|
static uint8_t packetCRC(char *data, uint16_t length, uint8_t startAt) {
|
||||||
uint16_t x = 0;
|
uint16_t x = 0;
|
||||||
|
|
||||||
|
|
|
@ -119,6 +119,8 @@ typedef struct PacketThreadDataS {
|
||||||
typedef void (*packetSender)(char *data, uint32_t length, void *userData);
|
typedef void (*packetSender)(char *data, uint32_t length, void *userData);
|
||||||
|
|
||||||
|
|
||||||
|
char *packetContentPack(uint16_t *length, char *format, ...);
|
||||||
|
void packetContentUnpack(char *buffer, char *format, ...);
|
||||||
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeData, char *input, uint16_t inputLength);
|
uint8_t packetDecode(PacketThreadDataT *threadData, PacketDecodeDataT *decodeData, char *input, uint16_t inputLength);
|
||||||
void packetDecodeDataDestroy(PacketDecodeDataT **packet);
|
void packetDecodeDataDestroy(PacketDecodeDataT **packet);
|
||||||
void packetDecodeDataStaticDestroy(PacketDecodeDataT *packet);
|
void packetDecodeDataStaticDestroy(PacketDecodeDataT *packet);
|
||||||
|
|
|
@ -27,12 +27,6 @@
|
||||||
|
|
||||||
#define PACKET_PROTOCOL_VERSION 1
|
#define PACKET_PROTOCOL_VERSION 1
|
||||||
|
|
||||||
#define PACKET_MAX_USER 16 // These need to match the configuration in the database.
|
|
||||||
#define PACKET_MAX_PASS 16 // Or better, use the database values.
|
|
||||||
#define PACKET_MAX_NAME 32
|
|
||||||
#define PACKET_MAX_EMAIL 32
|
|
||||||
#define PACKET_MAX_MESSAGE 256
|
|
||||||
|
|
||||||
|
|
||||||
// This enum is treated as BYTES in the code. Do not go over 255 entries.
|
// This enum is treated as BYTES in the code. Do not go over 255 entries.
|
||||||
typedef enum PacketTypeE {
|
typedef enum PacketTypeE {
|
||||||
|
@ -49,38 +43,12 @@ typedef enum PacketTypeE {
|
||||||
PACKET_TYPE_STRING,
|
PACKET_TYPE_STRING,
|
||||||
PACKET_TYPE_NUMBER,
|
PACKET_TYPE_NUMBER,
|
||||||
PACKET_TYPE_PROCEED,
|
PACKET_TYPE_PROCEED,
|
||||||
PACKET_TYPE_LOGIN,
|
|
||||||
PACKET_TYPE_SIGNUP,
|
PACKET_TYPE_SIGNUP,
|
||||||
PACKET_TYPE_SIGNUP_RESULT,
|
PACKET_TYPE_SIGNUP_RESULT,
|
||||||
|
PACKET_TYPE_LOGIN,
|
||||||
|
PACKET_TYPE_LOGIN_RESULT,
|
||||||
PACKET_TYPE_COUNT
|
PACKET_TYPE_COUNT
|
||||||
} PacketTypeT;
|
} PacketTypeT;
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
|
|
||||||
typedef struct PacketTypeVersionS {
|
|
||||||
uint32_t version;
|
|
||||||
} PacketTypeVersionT;
|
|
||||||
|
|
||||||
typedef struct PacketTypeLoginS {
|
|
||||||
char user[PACKET_MAX_USER];
|
|
||||||
char pass[PACKET_MAX_PASS];
|
|
||||||
} PacketTypeLoginT;
|
|
||||||
|
|
||||||
typedef struct PacketTypeSignUpS {
|
|
||||||
char user[PACKET_MAX_USER];
|
|
||||||
char pass[PACKET_MAX_PASS];
|
|
||||||
char first[PACKET_MAX_NAME];
|
|
||||||
char last[PACKET_MAX_NAME];
|
|
||||||
char email[PACKET_MAX_EMAIL];
|
|
||||||
} PacketTypeSignUpT;
|
|
||||||
|
|
||||||
typedef struct PacketTypeSignUpResultS {
|
|
||||||
uint8_t success;
|
|
||||||
char message[PACKET_MAX_MESSAGE];
|
|
||||||
} PacketTypeSignUpResultT;
|
|
||||||
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
|
|
||||||
#endif // PACKETS_H
|
#endif // PACKETS_H
|
||||||
|
|
Loading…
Add table
Reference in a new issue