Skip to content

Instantly share code, notes, and snippets.

@ashraf267
Created August 16, 2023 10:10
Show Gist options
  • Save ashraf267/bfb7cddcd5809c6001c24b0ca9124525 to your computer and use it in GitHub Desktop.
Save ashraf267/bfb7cddcd5809c6001c24b0ca9124525 to your computer and use it in GitHub Desktop.
This looks like it works, but needs some tweaks. At 11:10am 16/08/23
#include "Ui.h"
#include "Common.h"
#include "Communication.h"
#include "net_if.h"
#include "jsmn.h"
// string replace function
char *replace(
char const *const original,
char const *const pattern,
char const *const replacement)
{
size_t const replen = strlen(replacement);
size_t const patlen = strlen(pattern);
size_t const orilen = strlen(original);
size_t patcnt = 0;
const char *oriptr;
const char *patloc;
// find how many times the pattern occurs in the original string
for (oriptr = original; (patloc = strstr(oriptr, pattern)); oriptr = patloc + patlen)
{
patcnt++;
}
{
// allocate memory for the new string
size_t const retlen = orilen + patcnt * (replen - patlen);
char *const returned = (char *)malloc(sizeof(char) * (retlen + 1));
if (returned != NULL)
{
// copy the original string,
// replacing all the instances of the pattern
char *retptr = returned;
for (oriptr = original; (patloc = strstr(oriptr, pattern)); oriptr = patloc + patlen)
{
size_t const skplen = patloc - oriptr;
// copy the section until the occurence of the pattern
strncpy(retptr, oriptr, skplen);
retptr += skplen;
// copy the replacement
strncpy(retptr, replacement, replen);
retptr += replen;
}
// copy the rest of the string.
strcpy(retptr, oriptr);
}
return returned;
}
}
static int jsoneq(const char *json, jsmntok_t *tok, const char *s)
{
if (tok->type == JSMN_STRING && (int)strlen(s) == tok->end - tok->start &&
strncmp(json + tok->start, s, tok->end - tok->start) == 0)
{
return 0;
}
return -1;
}
// custom FetchWallet func
const char *FetchWallet(unsigned char *pcOut)
{
char *pBuf = "{\"walletId\": \"5149\"}";
char x[50] = "\\\"";
strcat(x, (char *)pcOut);
char y[50] = "\\\"";
strcat(x, y);
strcpy((char *)pcOut, x);
pBuf = replace(pBuf, "\"5149\"", (const char *)pcOut);
uint16_t uLen = strlen(pBuf);
char *pExtHeadr = "Content-Type: application/json\r\n";
short mySh = UIWireHttpSend("https://devapi.ucard.store/identity/Agent/login/wallet/complete", (uint8_t *)pBuf, uLen, pExtHeadr);
if (!(mySh == 0))
{
return TY_ERR;
}
int u_len = 250;
// char *response[u_len];
const char response[u_len];
mySh = UIWireHttpRecv((uint8_t *)response, (uint16_t *)u_len);
// jsmn code here
// Initialize jsmn parser
jsmn_parser parser;
jsmn_init(&parser);
// Estimate the number of tokens needed for parsing
int num_tokens = 20;
jsmntok_t tokens[num_tokens];
// Parse the JSON input
int ret = jsmn_parse(&parser, response, strlen(response), tokens, num_tokens);
if (ret < 0) {
printf("Error parsing JSON: %d\n", ret);
return 1;
}
jsmntok_t *value; // Declare the value variable outside the inner loop
char requestHash[100]; // Declare the variable to store the reqHash value
// Iterate through the JSON tokens
for (int i = 0; i < ret; i++) {
jsmntok_t *token = &tokens[i];
// Check if token is an object
if (token->type == JSMN_OBJECT) {
printf("Object:\n");
// Iterate through the object's key-value pairs
for (int j = i + 1; j < ret; j++) {
jsmntok_t *key = &tokens[j];
value = &tokens[j + 1]; // Assign value here
// Check if key is a string
if (key->type == JSMN_STRING) {
char key_str[key->end - key->start + 1];
strncpy(key_str, response + key->start, key->end - key->start);
key_str[key->end - key->start] = '\0';
printf("Key: %s\n", key_str);
// Check if value is a string
if (value->type == JSMN_STRING) {
char value_str[value->end - value->start + 1];
strncpy(value_str, response + value->start, value->end - value->start);
value_str[value->end - value->start] = '\0';
printf("Value: %s\n", value_str);
// Check if the key is "requestHash"
if (strcmp(key_str, "requestHash") == 0) {
strncpy(requestHash, value_str, sizeof(requestHash));
}
}
}
// Skip the value token
j++;
}
// Move the main index to the end of the object
i = value->end;
}
}
return requestHash;
// return 0
}
// custom VerifyOTP func
short VerifyOTP(unsigned char *pcOut)
{
char *pBuf = "{\"requestHash\": \"363P9e2062c63b574fd090adfad5db78fa5b\", \"otp\": \"7777\"}"; // json body
char x[50] = "\\\"";
strcat(x, (char *)pcOut);
char y[50] = "\\\"";
strcat(x, y);
strcpy((char *)pcOut, x); // input padded
pBuf = replace(pBuf, "\"7777\"", (const char *)pcOut); // 7777 replaced with user entered otp
uint16_t uLen = strlen(pBuf);
char *pExtHeadr = "Content-Type: application/json\r\n";
short mySh = UIWireHttpSend("https://devapi.ucard.store/identity/Agent/login/wallet/complete", (uint8_t *)pBuf, uLen, pExtHeadr);
if (!(mySh == 0))
{
return TY_ERR;
}
int u_len = 250;
// char *response[u_len];
const char response[u_len];
mySh = UIWireHttpRecv((uint8_t *)response, (uint16_t *)u_len);
// jsmn code here
int i;
int r;
jsmn_parser p;
jsmntok_t t[128]; /* We expect no more than 128 tokens */
jsmn_init(&p);
r = jsmn_parse(&p, response, strlen(response), t,
sizeof(t) / sizeof(t[0]));
if (r < 0)
{
printf("Failed to parse JSON: %d\n", r);
return 1;
}
/* Assume the top-level element is an object */
if (r < 1 || t[0].type != JSMN_OBJECT)
{
printf("Object expected\n");
return 1;
}
// if needed, declare vars here
for (i = 1; i < r; i++)
{
if (jsoneq(response, &t[i], "message") == 0)
{
/* We may use strndup() to fetch string value */
printf("- User: %.*s\n", t[i + 1].end - t[i + 1].start,
response + t[i + 1].start);
i++;
}
else if (jsoneq(response, &t[i], "statusCode") == 0)
{
printf("- Admin: %.*s\n", t[i + 1].end - t[i + 1].start,
response + t[i + 1].start);
i++;
}
else if (jsoneq(response, &t[i], "isSuccessful") == 0)
{
printf("- Admin: %.*s\n", t[i + 1].end - t[i + 1].start,
response + t[i + 1].start);
i++;
}
else
{
printf("Unexpected key: %.*s\n", t[i].end - t[i].start,
response + t[i].start);
}
}
// return
return TY_OK;
}
// custom UIInputOTP func that accepts the reqHash
short UIInputOTP(unsigned char ucOutXmode, unsigned char *pcOut, unsigned char *pucOutLen, int iTimeout, const char *requestHash)
{
unsigned char ucInputLenMax; /* ������볤�� */
unsigned char ucInputCnt; /* ������� */
// unsigned char ucKey;
unsigned char ucDisplayLen;
char acCodeBuff[64];
short sRC;
// ucInputLenMax = 12; // max no of characters, I believe
ucInputLenMax = 4;
ucInputCnt = 0;
// Lib_LcdDrowArea(DEFAULT_FORG_COLOR, 0, 30, 320, 140);
Lib_LcdDrowArea(RGB565_WHITE, 0, 30, 320, 210);
// Lib_LcdDrowArea(DEFAULT_BACK_COLOR, 0, 170, 320, 70);
pcOut[0] = 0;
while (1)
{
// DRAW_TITLE(TIP_ENTER_AMOUNT);
DRAW_TITLE_X("Verify Number");
// UILabelMyText("Enter digit sent to your Mobile no", ALIGN_M, RGB565_BLACK, RGB565_WHITE, 0, 50 + 10);
UILabelMyText((char *)requestHash, ALIGN_M, RGB565_BLACK, RGB565_WHITE, 0, 50 + 10);
UILabelShopName("Press O to continue, X to cancel!");
memset(acCodeBuff, 0, sizeof(acCodeBuff)); // fills the whole acCodeBuff (64 bytes) with 0
ucDisplayLen = (unsigned char)strlen((char *)pcOut);
if (ucDisplayLen < 1)
{
memcpy(acCodeBuff, "0000", 4); // copies n (4) chars from src ("0.00") to dest (acCodeBuff), in this case
// if the below causes any error, remove it
memcpy(acCodeBuff + 10 - ucDisplayLen, pcOut, ucDisplayLen);
ucDisplayLen = 10;
}
else
{
// memcpy(acCodeBuff, pcOut, ucDisplayLen-2);
memcpy(acCodeBuff, pcOut, ucDisplayLen);
// acCodeBuff[ucDisplayLen-2] = '.';
// memcpy(acCodeBuff+ucDisplayLen-1, pcOut+ucDisplayLen-2, 2);
// ucDisplayLen = ucDisplayLen+1;
}
// ShowAmount(acCodeBuff, 90, DEFAULT_BACK_COLOR, DEFAULT_FORG_COLOR);
ShowAmount(acCodeBuff, 90, RGB565_BLACK, RGB565_WHITE);
// ��ȡ��������
sRC = UIWaitKey(iTimeout, 1);
// �ȴ�ʱ���ѳ�ʱ
if (UI_INPUT_TIMEOUT == sRC)
{
return UI_INPUT_TIMEOUT;
}
if ((sRC >= '0') && (sRC <= '9'))
{
// �����ʼ����0��Ч
if ((0 == ucInputCnt) && ('0' == sRC))
{
continue;
}
if (ucInputCnt < ucInputLenMax)
{
// ���水��ֵ��pcOut
pcOut[ucInputCnt++] = sRC;
pcOut[ucInputCnt] = 0; // �ַ���������
// TRACEBUF(pcOut,ucInputCnt);
}
}
else if (UI_INPUT_CLEAR == sRC)
{
if (ucInputCnt > 0)
{
pcOut[--ucInputCnt] = 0;
// UIClearRect(0, 3, LCD_MAX_SEG, 1);
}
}
else if (UI_INPUT_ENTER == sRC)
{
pcOut[ucInputCnt] = 0; /* �ַ��������� */
*pucOutLen = ucInputCnt;
TRACE("ucInputCnt==%d \r\n", ucInputCnt);
TRACEBUF(pcOut, ucInputCnt);
// return UI_INPUT_ENTER;
if (!(pcOut == NULL))
{
VerifyOTP(pcOut);
// then set sRC to go to custom Main menu
return UI_INPUT_ENTER;
}
else
{
return UI_INPUT_ENTER_NULL;
}
}
else if (UI_INPUT_CANCEL == sRC)
{
memset(pcOut, 0, ucInputCnt);
*pucOutLen = 0;
ucInputCnt = 0;
return UI_INPUT_CANCEL;
}
else if (UI_INPUT_MENU == sRC)
{
*pucOutLen = 0;
return UI_INPUT_MENU;
}
else
{
}
}
}
// custom UIInputWallet func
short UIInputWallet(unsigned char ucOutXmode, unsigned char *pcOut, unsigned char *pucOutLen, int iTimeout)
{
unsigned char ucInputLenMax; /* ������볤�� */
unsigned char ucInputCnt; /* ������� */
// unsigned char ucKey;
unsigned char ucDisplayLen;
char acCodeBuff[64];
short sRC;
ucInputLenMax = 10; // max no of characters, I believe
ucInputCnt = 0;
// Lib_LcdDrowArea(DEFAULT_FORG_COLOR, 0, 30, 320, 140);
Lib_LcdDrowArea(RGB565_WHITE, 0, 30, 320, 210);
// Lib_LcdDrowArea(DEFAULT_BACK_COLOR, 0, 170, 320, 70);
pcOut[0] = 0;
// my vars
const char *reqHash;
unsigned char ucCashLen, ucSumArray[12];
while (1)
{
// DRAW_TITLE(TIP_ENTER_AMOUNT);
DRAW_TITLE_X("Welcome");
UILabelMyText(" Enter Wallet ID", ALIGN_L, RGB565_BLACK, RGB565_WHITE, 0, 50 + 10);
UILabelShopName("Press O to send OTP, X to cancel!");
memset(acCodeBuff, 0, sizeof(acCodeBuff));
ucDisplayLen = (unsigned char)strlen((char *)pcOut);
if (ucDisplayLen < 1)
{
memcpy(acCodeBuff, "0000000000", 10); // copies n (4) chars from src ("0.00") to dest (acCodeBuff), in this case
// if the below causes any error, remove it
memcpy(acCodeBuff + 10 - ucDisplayLen, pcOut, ucDisplayLen);
ucDisplayLen = 10;
}
else
{
// memcpy(acCodeBuff, pcOut, ucDisplayLen-2);
memcpy(acCodeBuff, pcOut, ucDisplayLen);
// acCodeBuff[ucDisplayLen-2] = '.';
// memcpy(acCodeBuff+ucDisplayLen-1, pcOut+ucDisplayLen-2, 2);
// ucDisplayLen = ucDisplayLen+1;
}
// ShowAmount(acCodeBuff, 90, DEFAULT_BACK_COLOR, DEFAULT_FORG_COLOR);
ShowAmount(acCodeBuff, 90, RGB565_BLACK, RGB565_WHITE);
// ��ȡ��������
sRC = UIWaitKey(iTimeout, 1);
// �ȴ�ʱ���ѳ�ʱ
if (UI_INPUT_TIMEOUT == sRC)
{
return UI_INPUT_TIMEOUT;
}
if ((sRC >= '0') && (sRC <= '9'))
{
// �����ʼ����0��Ч
if ((0 == ucInputCnt) && ('0' == sRC))
{
continue;
}
if (ucInputCnt < ucInputLenMax)
{
// ���水��ֵ��pcOut
pcOut[ucInputCnt++] = sRC;
pcOut[ucInputCnt] = 0; // �ַ���������
// TRACEBUF(pcOut,ucInputCnt);
}
}
else if (UI_INPUT_CLEAR == sRC)
{
if (ucInputCnt > 0)
{
pcOut[--ucInputCnt] = 0;
// UIClearRect(0, 3, LCD_MAX_SEG, 1);
}
}
else if (UI_INPUT_ENTER == sRC)
{
pcOut[ucInputCnt] = 0; /* �ַ��������� */
*pucOutLen = ucInputCnt;
TRACE("ucInputCnt==%d \r\n", ucInputCnt);
TRACEBUF(pcOut, ucInputCnt);
if (pcOut != NULL)
{
// TODO: this code needs a rewrite
reqHash = FetchWallet(pcOut);
sRC = UIInputOTP(ALIGN_L, ucSumArray, &ucCashLen, iTimeout, reqHash);
return UI_INPUT_ENTER;
}
else
{
}
// return UI_INPUT_ENTER
}
else if (UI_INPUT_CANCEL == sRC)
{
memset(pcOut, 0, ucInputCnt);
*pucOutLen = 0;
ucInputCnt = 0;
return UI_INPUT_CANCEL;
}
else if (UI_INPUT_MENU == sRC)
{
*pucOutLen = 0;
return UI_INPUT_MENU;
}
else
{
}
}
}
short UISplashScreen(char *pcAmt, unsigned short usY, unsigned short usForeCl, unsigned short usBlackCl)
{
uint16_t *pBuf;
int iRes;
unsigned int Bufsize;
uint16_t height = 64;
Bufsize = 320 * height * 2;
pBuf = (uint16_t *)Lib_malloc(Bufsize);
if (pBuf == NULL)
{
return -1;
}
WIDGET_TEXT Text;
Text.ForegroundColorText = usForeCl;
Text.BackgroundColorText = usBlackCl;
Text.h = height;
Text.FontTextEn = FONT_28X56;
Text.FontTextCn = FONT_56X56;
Text.pText = (uint8_t *)pcAmt;
Text.TextLen = strlen((const char *)Text.pText);
Text.Align = ALIGN_M;
Text.w = 320;
iRes = Lib_LcdCreatText(&Text, pBuf, Bufsize);
if (0 > iRes)
{
Lib_free(pBuf);
return -1;
}
Lib_LcdDispMemcpy(pBuf, 0, usY, Text.w, Text.h);
UILabelMyText("Welcome to UCARD", ALIGN_M, RGB565_WHITE, BGBACK_PURPLE, 0, (170 + 10));
Lib_LcdRefresh();
Lib_free(pBuf);
return TY_OK; // 0
}
// to be called in main.c
// ucOutXmode:- sets the align
short UIShow(unsigned char ucOutXmode, int iTimeout)
{
short sRC;
Lib_LcdDrowArea(BGBACK_PURPLE, 0, 30, 320, 210);
while (1)
{
// call UISplashScreen func
UISplashScreen("UCARD", 90, DEFAULT_BACK_COLOR, BGBACK_PURPLE);
sRC = UIWaitKey(iTimeout, 1);
if (UI_INPUT_TIMEOUT == sRC)
{
return UI_INPUT_TIMEOUT;
}
if (UI_INPUT_ENTER == sRC)
{
return UI_INPUT_ENTER;
}
else if (UI_INPUT_CANCEL == sRC)
{
return UI_INPUT_CANCEL;
}
else if (UI_INPUT_MENU == sRC)
{
return UI_INPUT_MENU;
}
else
{
// an empty return gives a warning
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment