RESTful API sample program.

  • A demonstration site for this sample is available.
  • To use this sample, create an account for the customer on the demonstration site, read the barcode with this sample, exchange via Wifi with RESTful API (JSON format), and enter the product name of the barcode. It can be displayed on the OPH.
  • Please refer to the following for the specifications of the interface (RESTful API) with the demonstration site.
  • First, JSON-based token authentication is performed with JWT (JSON Web Token) at the following URL.

    https://www.optoapsv.com/ophsv/token/

    After that, the OPH side POSTs the request in JSON format to the following URL and receives the response in JSON format.

    https://www.optoapsv.com/ophsv/oph_public_api/v1/

    The general flow is described below.

    1. [OPH] Request user authentication.
    2. [Demonstration server] If authentication is OK, return the token.
    3. [OPH] Request by attaching the token inside the API.
    4. [Demonstration server] Returns the result of the API.

    The following is a description of the extra header and body at the time of POST. It is linked with the above number. The [Token] of 2 contains the character string obtained from the demonstration server. Set the [Token] of 3 to the [Token] of 2. For more information, see [RFC7519] JSON Web Token (JWT).

    No. Type Explanation
    1 Request extra header "Accept-Encoding: identity\r\nContent-Type: application/json\r\n"
    1 Request body
    {
      "username": "XXXXXXXXXX",
      "password": "YYYYYYYYYY",
      "email": ""
    }
    
    2 Response body {"token": "[Token]"}
    3 Request extra header "Accept-Encoding: identity\r\nContent-Type: application/json\r\nAuthorization: JWT [Token]\r\nConnection: close\r\n"
    3 Request body
    {
      "request_id": "000001",
      "request_name": "get item name",
      "requester": "demo",
      "request_param": {
        "username": "XXXXXXXXXX",
        "terminal_id": "7890",
        "barcode": "4902102072618",
        "language_code": "en"
      }
    }
    
    4 Response body
    {
      "request_id": "000001",
      "request_name": "get item name",
      "requester": "demo",
      "request_param": {
        "username": "XXXXXXXXXX",
        "terminal_id": "7890",
        "barcode": "4902102072618",
        "language_code": "en"
      },
      "results": [
        {
          "Barcode": "4902102072618",
          "Description": "Coca Cola 500ml"
        }
      ],
      "status": "000"
    }
    

    The variable names and values specified in JSON format of RESTful API are as follows.

    Variable Explanation
    request_id Request serial number
    request_name Request name
    requester Request source
    request_param JSON-formatted request parameters
    username Username
    terminal_id Terminal ID
    barcode Read barcode
    language_code Product name, notation language
    "ja": Japanese
    "en": English
    results JSON-formatted response
    Barcode Response barcode
    Description Product name of the response barcode
    status API execution result
    "000": Normal termination
    "004": The target barcode is not registered in the server
    "501": API parameter error
    "999": Server setting error

To use this sample, link the following library to your application program.

Header file:
lib.h : System E6.0 or later.
http_request.h
jansson.h
jansson_config.h
jansson_log.h
CodeConversion.h : ver.1.1.1 or later.
AdvancedMenu.h
Library file:
libHttpRequest.a
libJansson.a
libCodeConversion.a : ver.1.1.1 or later.
libAdvancedMenu.a
libSTARTUPOPH5000.a : System E6.0 or later.

Note:

When adding library files, link them in the above order.

Procedure

1. Create a new account.

2. Login with the account you created earlier.

3. Open the JSON demonstration page

4. For the sample code jsonRequest.c, change the define of AUTH_USER_NAME and AUTH_PASSWORD to the created account.

5. Read the barcode with this sample application.

6. The product name will be displayed on the OPH5000i screen.



Sample: main.c
#include <stdio.h>
#include "lib.h"
#include "http_request.h"
#include "jsonRequest.h"
#include "AdvancedMenu.h"


#define BUFFER_SIZE 256

//Option flag for http
#define HTTP_OPTION      HTTP_FLAG_BYPASSMODE

//Timeout for WLAN connection
#define WLAN_CONNECTION_TIMEOUT     (30000/20)
#define SERVER_RESPONSE_TIMEOUT     (15000/20)

#define HTTP_SUCCESS                        0
#define HTTP_WLAN_TIMEOUT_ERROR             1
#define HTTP_SERVER_CONNECTION_ERROR        2
#define HTTP_SERVER_RESPONSE_ERROR          3
#define HTTP_SERVER_TIMEOUT_ERROR           4
#define HTTP_SYSTEM_ERROR                   (-1)

char* appJob(char* barcode);
char* appPost(char* barcode);

// Prototypes
void task1(void);

///////////////////////////////////////////////////////////////////
// Color palettes
///////////////////////////////////////////////////////////////////
#define MENU_FORE_COLOR     RGB_WHITE
#define MENU_BACK_COLOR     0x427cbe    //Dull blue
#define MENU_BUTTON_COLOR   RGB_YELLOW
#define MENU_APPLY_COLOR    0xfcd9ff    //Color of Start icon (Light pink)
#define MENU_SELECT_COLOR   0x284a70    //Dark blue

#define FORE_COLOR          RGB_WHITTE
#define BACK_COLOR          0xf7f7f7    //Light gray
#define SELECT_COLOR        RGB_BLUE
#define DISABLE_COLOR       0xb0b0b0    //Gray
#define GIUDE_BUTTON        RGB_BLUE
#define APPLY_COLOR         RGB_MAGENTA
#define TITLE_SET_COLOR     RGB_BLUE
#define TITLE_TASK_COLOR    0x008000    //Dark Green

static const AM_ColorPalette CustomColor[] = {
    //ForeColor,        BackColor,        Select_ForeColor, Select_BackColor,  Control_ForeColor
    { MENU_FORE_COLOR,  MENU_BACK_COLOR,  RGB_WHITE,        MENU_SELECT_COLOR, MENU_BUTTON_COLOR }, //#0: Task menu base color
    { MENU_FORE_COLOR,  MENU_BACK_COLOR,  0,                0,                 MENU_APPLY_COLOR  }, //#1: Task menu apply color
    { RGB_BLACK,        BACK_COLOR,       RGB_WHITE,        SELECT_COLOR,      GIUDE_BUTTON      }, //#2: Base color
    { RGB_WHITE,        RGB_BLUE,         0,                0,                 0                 }, //#3: Title of Setting
    { GIUDE_BUTTON,     BACK_COLOR,       0,                0,                 GIUDE_BUTTON      }, //#4: Guide color
    { RGB_WHITE,        TITLE_TASK_COLOR, 0,                0,                 0                 }, //#5: Title 0f tasks
    { RGB_BLACK,        RGB_WHITE,        RGB_BLACK,        RGB_YELLOW,        RGB_BLUE          }, //#6: Input field color
    { APPLY_COLOR,      BACK_COLOR,       0,                0,                 APPLY_COLOR       }, //#7: Apply color
};
#define PX_MENU           0	 // Task menu base color
#define PX_MENU_APPLY     1  // Task menu apply color
#define PX_BASE           2  // Base color
#define PX_TITLE_SETTING  3  // Title of Setting
#define PX_GUIDE          4  // Guide color
#define PX_TITLE_TASK     5  // Title 0f tasks
#define PX_EDIT           6  // Input field color
#define PX_APPLY          7  // Apply color

///////////////////////////////////////////////////////////////////
// Task menu screen
///////////////////////////////////////////////////////////////////

// Options for the task menu screen
static const AM_Option MenuOption = {
    MENU_FORE_COLOR,                                // MenuForeColor
    DISABLE_COLOR,                                  // MenuDisabledForeColor
    MENU_BACK_COLOR,                                // MenuBackColor
    sizeof(CustomColor) / sizeof(AM_ColorPalette),  	// NumberOfColorPalette
    (pAM_ColorPalette)CustomColor,                  // ColorPalettes
    0,                                              // OptionFlag
    HUGE_FONT,                                      // DefaultFont
    1                                               // DefaultLineSpacing
};

// Definition of the task menu screen
// Item ID
enum _MAIN_ITEM_ID {
    MENU_ID_TASK1 = 1,
    MENU_ID_NOTASK,
    MENU_ID_START,
};
// Table of the menu items for the task menu screen
static const AM_MenuItem MainMenuTable[] = {
    //   itemID,        y,           x, menuText,     Palette,       visible, enabled, selectable, showControl,   checked, font
        {MENU_ID_TASK1, 1,           1, " Task #1 ",  PX_MENU,       true,    true,    true,       AM_NO_CONTROL},
        {MENU_ID_NOTASK,1,           1, "No task",    PX_MENU,       false,   true,    false,      AM_NO_CONTROL},
        {MENU_ID_START, AM_PIX(129), 0, "Start task", PX_MENU_APPLY, true,    true,    false,      AM_SCAN_ICON,  false,   MEDIUM_FONT},
        {-1}
};

void main(void)
{
    //Log settings
    DBG_HTTP_REQUEST_API = 1;
    DBG_HTTP_RECEIVED_DATA = 1;
    DBG_HTTP_SENT_DATA = 1;

    OsStatus(ON);
    SetEcho(OFF);

    MENU_HANDLE hMenu;
    int event;
    int task;

    hMenu = AM_CreateMenu(MainMenuTable, (const pAM_Option)&MenuOption);

    while (1) {
        // Update "enabled" property of the [Start] icon.
        AM_SetEnabled(hMenu, MENU_ID_START, AM_IsVisible(hMenu, MENU_ID_TASK1));
        // Display "No task" when the [start] icon is disabled.
        AM_SetVisible(hMenu, MENU_ID_NOTASK, !AM_IsEnabled(hMenu, MENU_ID_START));

        // Update task menu screen.
        AM_ShowMenu(hMenu, AM_SELECT_ANY_ID);

        while (1) {
            event = AM_ExecMenu(hMenu);
            if (event == SCAN_KEY) {
                // Open screen of selected task.
                task = AM_GetSelectedLine(hMenu);
                switch (task) {
                case MENU_ID_TASK1:
                    task1();
                    break;
                default:
                    continue;
                }
                break;
            }
        }
    }
}

char returnValue[BUFFER_SIZE];
char* appJob(char* barcode)
{
    char* value = NULL;

    //Enable WLAN
    SysSetWLANPower(SYS_WLAN_POWER_AUTO);
    SysWLANInit(NULL);

    //Init HttpRequest
    HTTP_InitHttpRequest();
    value = appPost(barcode);

    //Deinit HttpRequest
    HTTP_DeinitHttpRequest();
    return value;
}

char* appPost(char* barcode)
{
    int status;
    unsigned int waitStartTick;
    bool abortFlag = false;
    HTTP_REQUEST_HANDLE hRequest;
    char responsePhase;
    unsigned int responseStatus;
    char* content;
    unsigned int content_length;
    char* header;
    unsigned int headerLength;
    int result;
    AutoPowerDown(APD_DISABLE, 0);

    char* headerData = NULL;
    char* submitData = NULL;
    char* encodeData = NULL;
    char* description = NULL;
    size_t headerDataSize = 0;
    size_t submitDataSize = 0;

    memset(returnValue, 0, BUFFER_SIZE);

    headerData = (char*)malloc(BUFFER_SIZE * 2);
    submitData = (char*)malloc(BUFFER_SIZE);
    encodeData = (char*)malloc(BUFFER_SIZE);
    description = (char*)malloc(BUFFER_SIZE);

    if (headerData == NULL || submitData == NULL || encodeData == NULL || description == NULL) {
        if (headerData != NULL) {
            free(headerData);
        }
        if (submitData != NULL) {
            free(submitData);
        }
        if (encodeData != NULL) {
            free(encodeData);
        }
        if (description != NULL) {
            free(description);
        }
        strcpy(returnValue, "Cannot allocate memory.");
        return returnValue;
    }

    memset(headerData, 0, BUFFER_SIZE * 2);
    memset(submitData, 0, BUFFER_SIZE);
    memset(encodeData, 0, BUFFER_SIZE);
    memset(description, 0, BUFFER_SIZE);

    //Check WLAN connection
    waitStartTick = GetTickCount();
    do {
        SysGetWLANConnectStatus(&status);
        if (status == SYS_WLAN_STATUS_CONNECTED)
            break;
        Idle();
    } while (GetTickCount() - waitStartTick < WLAN_CONNECTION_TIMEOUT);
    if (status != SYS_WLAN_STATUS_CONNECTED) {
        strcpy(returnValue, ">WLAN timeout!");
        return returnValue;
    }

    // ************************* REQUEST JWT START ****************************************
    submitDataSize = getAuthData(submitData, BUFFER_SIZE);
    headerDataSize = getAuthHeader(headerData, BUFFER_SIZE * 2);
    if (!submitDataSize || !headerDataSize) {
        strcpy(returnValue, ">Auth error!");
        abortFlag = true;
    }
    else {
        //Create HTTP POST request and send it to HTTP server
        hRequest = HTTP_CreateRequest(
            URL_AUTH,
            HTTP_REQ_POST,
            submitData,
            submitDataSize,
            headerData,
            SERVER_RESPONSE_TIMEOUT,
            HTTP_OPTION);

        if (hRequest) {
            while (1) {
                //Wait for HTTP response
                if (HTTP_GetResponse(hRequest,
                    &responsePhase,
                    &responseStatus,
                    &content,
                    &content_length,
                    &header, &headerLength)) {
                    switch (responsePhase) {
                    case HTTP_REQUEST_CONNECTION_ERROR:
                        strcpy(returnValue, ">CONNECTION_ERROR!");
                        abortFlag = true;
                        break;
                    case HTTP_REQUEST_SYSTEM_ERROR:
                        strcpy(returnValue, ">SYSTEM_ERROR!");
                        abortFlag = true;
                        break;
                    case HTTP_REQUEST_TIMEOUT:
                        strcpy(returnValue, ">TIMEOUT!");
                        abortFlag = true;
                        break;
                    case HTTP_REQUEST_FINISHED:
                        if (responseStatus == 200) {
                            if (content_length) {
                                SetTextColor(RGB_BLUE);
                                memset(headerData, 0, BUFFER_SIZE * 2);
                                headerDataSize = getTokenHeader(content, headerData,
                                    BUFFER_SIZE * 2);
                                SetTextColor(RGB_BLACK);
                                if (!headerDataSize) {
                                    strcpy(returnValue, ">token error!");
                                    abortFlag = true;
                                }
                            }
                            else {
                                strcpy(returnValue, "0 bytes received");
                                abortFlag = true;
                            }
                        }
                        else {
                            sprintf(returnValue, ">FINISHED status=%d", responseStatus);
                            abortFlag = true;
                        }
                        break;
                    default:
                        Idle();
                        continue;
                    }
                }
                else {
                    strcpy(returnValue, ">System error!");
                    abortFlag = true;
                }
                break;
            }
            HTTP_CloseRequest(hRequest);
        }
        else {
            strcpy(returnValue, ">Server failed");
            abortFlag = true;
        }
        if (abortFlag) {
            return returnValue;
        }
        // ************************* REQUEST JWT END ****************************************

        // **************************** REQUEST RESTful API START *****************************

        memset(submitData, 0, BUFFER_SIZE);
        submitDataSize = getSubmitData(submitData, BUFFER_SIZE, barcode);
        if (!submitDataSize) {
            strcpy(returnValue, ">submit data error!");
            abortFlag = true;
        }

        //Create HTTP POST request and send it to HTTP server
        hRequest = HTTP_CreateRequest(
            REQUEST_URL,
            HTTP_REQ_POST,
            submitData,
            submitDataSize,
            headerData,
            SERVER_RESPONSE_TIMEOUT,
            HTTP_OPTION);
        if (hRequest) {
            while (1) {
                //Wait for HTTP response
                if (HTTP_GetResponse(hRequest,
                    &responsePhase,
                    &responseStatus,
                    &content,
                    &content_length,
                    &header, &headerLength)) {
                    switch (responsePhase) {
                    case HTTP_REQUEST_CONNECTION_ERROR:
                        strcpy(returnValue, ">CONNECTION_ERROR!");
                        break;
                    case HTTP_REQUEST_SYSTEM_ERROR:
                        strcpy(returnValue, ">SYSTEM_ERROR!");
                        break;
                    case HTTP_REQUEST_TIMEOUT:
                        strcpy(returnValue, ">TIMEOUT!");
                        break;
                    case HTTP_REQUEST_FINISHED:
                        if (responseStatus == 200) {
                            if (content_length) {
                                SetTextColor(RGB_BLUE);
                                result = jsonAnalysis(content);
                                if (result == 0) {
                                    result = getDescriptionFromJson(content, description);
                                    if (result == 0) {
                                        strcpy(returnValue, description);
                                    }
                                    else {
                                        strcpy(returnValue, "Unknown.");
                                    }
                                }
                                else {
                                    strcpy(returnValue, ">JSON analysis error!");
                                }
                                SetTextColor(RGB_BLACK);
                            }
                            else {
                                strcpy(returnValue, "0 bytes received");
                            }
                        }
                        else {
                            sprintf(returnValue, ">FINISHED status=%d", responseStatus);
                        }
                        break;
                    default:
                        Idle();
                        continue;
                    }
                }
                else {
                    strcpy(returnValue, ">System error!");
                }
                break;
            }
            HTTP_CloseRequest(hRequest);
        }
        else {
            strcpy(returnValue, ">Server failed");
        }
    }

    // ************************* REQUEST RESTful API END **************************************

    AutoPowerDown(APD_ENABLE, 0);
    if (headerData != NULL) {
        free(headerData);
    }
    if (submitData != NULL) {
        free(submitData);
    }
    if (encodeData != NULL) {
        free(encodeData);
    }
    if (description != NULL) {
        free(description);
    }
    return returnValue;
}

////////////////////////////////////////////////////
// Task #1: Read EAN/UPC code
////////////////////////////////////////////////////

// Options for task #1, #2  and #3 screen
static const AM_Option TaskOption = {
    RGB_BLACK,                                      // MenuForeColor
    DISABLE_COLOR,                                  // MenuDisabledForeColor
    BACK_COLOR,                                     // MenuBackColor
    sizeof(CustomColor) / sizeof(AM_ColorPalette),  	// NumberOfColorPalette
    (pAM_ColorPalette)CustomColor,                  // ColorPalettes
    0,                                              // OptionFlag
    MEDIUM_FONT,                                    // DefaultFont
    1                                               // DefaultLineSpacing
};

// Text field parameter
static char editBuf[60 + 1] = { "" };
static const AM_EditParam editParam1 = {
    20,                 // MaxDigits
    0,                  // Cursor foregraund Color
    0,                  // Cursor backgraund Color
    0,                  // Shift mode foregraund Color
    0,                  // Shift mode backgraund Color
    0,                  // EditOption
    NULL,               // alphaCandidateTable
    editBuf,         // Value
    sizeof(editBuf)  // ValueBufSize
};
static const AM_EditParam editParam2 = {
    20                  // MaxDigits
};
static const AM_EditParam editParam3 = {
    20                  // MaxDigits
};


// Definition of the task #1 screen
// Item ID
enum _TASK1_ITEM_ID {
    TASK1_ID_RESULT = 1,
    TASK1_ID_NAME,
};

// Table of the menu items for task #1 screen
static const AM_MenuItem Task1MenuTable[] = {
    //   itemID,           y,           x,          menuText,              Palette,       visible, enabled, selectable, showControl,   checked, font
        {0,                0,           0,          "Task #1",             PX_TITLE_TASK, true,    true,    false,      AM_TITLE_LINE, false,   LARGE_FONT},
        {0,                2,           1,          "Read EAN/UPC code.",  PX_BASE,       true,    true,    false,      AM_NO_CONTROL},
        {TASK1_ID_RESULT,  4,           1,          "",                    PX_BASE,       true,    true,    false,      AM_NO_CONTROL},
        {TASK1_ID_NAME,    5,           1,          (void*)&editParam1,   PX_EDIT,       true,    true,    false,      AM_TEXT_EDIT,  false,   MEDIUM_FONT, AM_MULTI_START},
        {0,                6,           1,          (void*)&editParam2,   PX_EDIT,       true,    true,    false,      AM_TEXT_EDIT,  false,   MEDIUM_FONT, AM_MULTI_MID},
        {0,                7,           1,          (void*)&editParam3,   PX_EDIT,       true,    true,    false,      AM_TEXT_EDIT,  false,   MEDIUM_FONT, AM_MULTI_END},
        {0,                AM_PIX(114), 0,          "Read barcode",        PX_GUIDE,      true,    true,    false,      AM_SCAN_ICON},
        {0,                AM_PIX(129), 0,          "Exit",                PX_GUIDE,      true,    true,    false,      AM_CLEAR_ICON},
        {-1}
};

void task1(void)
{
    MENU_HANDLE hMenu;
    int event;
    char barcodebuff[13 + 1];
    AM_BarcodeBuffer buffer;
    char* resultValue = NULL;
    char description[BUFFER_SIZE];
    memset(description, 0, BUFFER_SIZE);
    memset(editBuf, 0, sizeof(editBuf));

    buffer.dataBuf = barcodebuff;
    buffer.dataBufLength = sizeof(barcodebuff);

    hMenu = AM_CreateMenu(Task1MenuTable, (const pAM_Option)&TaskOption);

    // Set option commands
    //  B0:  Disable all symbology
    //  R1:  Enable UPC
    //  R4:  Enable EAN/JAN
    AM_ConfigBarcodeReader(hMenu, &buffer, "B0R1R4");

    AM_ShowMenu(hMenu, AM_SELECT_NO_ID);
    AM_EnableBarcodeReader(hMenu);

    while (1) {
        event = AM_ExecMenu(hMenu);
        // Waiting scan
        if (event == AMENU_BARCODE_READ) {
            AM_DisableBarcodeReader(hMenu);
            AM_SetText(hMenu, TASK1_ID_NAME, "");
            // Got result
            AM_SetText(hMenu, TASK1_ID_RESULT, barcodebuff);
            resultValue = appJob(barcodebuff);
            if (resultValue) {
                strcpy(editBuf, resultValue);
            }
            else {
                strcpy(editBuf, "");
            }
            AM_SetText(hMenu, TASK1_ID_NAME, editBuf);
            AM_EnableBarcodeReader(hMenu);
            continue;
        }
        else if (event == CLR_KEY) {
            //Exit
            break;
        }
    }
    AM_DisableBarcodeReader(hMenu);

    AM_ReleaseMenu(hMenu);
    return;
}


Sample: jsonRequest.h
#ifndef JSON_REQUEST_H_
#define JSON_REQUEST_H_

#include "jansson.h"

#define JSON_LOG_TAG "[JSON]"

#define JSON_SUCCESS                        0
#define JSON_SYSTEM_ERROR                   (-1)

#define URL_AUTH 	"https://www.optoapsv.com/ophsv/token/"
#define REQUEST_URL "https://www.optoapsv.com/ophsv/oph_public_api/v1/"

int jsonAnalysisFromJson(json_t* pRoot);
int jsonAnalysis(const char* pText);
int getDescriptionFromJson(const char* pText, char* pEncodeStr);
size_t getAuthData(char* pData, size_t dataSize);
size_t getAuthHeader(char* pData, size_t dataSize);
size_t getTokenHeader(const char* pText, char* pTokenHeader, size_t tokenHeaderSize);
size_t getSubmitData(char* pSubmitData, size_t submitDataSize, char* pSetValue);

#endif /* JSON_REQUEST_H_ */

Sample: jsonRequest.c
/*
 * jansson
 *
 * jansson is The MIT License
 * Refer https://opensource.org/licenses/mit-license.php
 */

#include <stdio.h>
#include <string.h>
#include "lib.h"
#include "logapi.h"
#include "CodeConversion.h"
#include "jsonRequest.h"

 /*
  * Need to create user and password.
  * Refer https://www.optoapsv.com/ophsv/en/oph_csv_web/create_account/
  */
#define AUTH_USER_NAME "XXXXXXXXXX"  // Need to change the created user name.
#define AUTH_PASSWORD  "YYYYYYYYYY"  // Need to change the created password.

  //Log setting
int DBG_JSON_API_ERROR = 1;
int DBG_JSON_API_INFO = 1;
int DBG_JSON_API_DEBUG = 1;

int DBG_JANSSON_API_ERROR = 1;
int DBG_JANSSON_API_INFO = 1;
int DBG_JANSSON_API_DEBUG = 0;

char jsonApiVersion[] = "1.00";

static unsigned int gRequestId = 0;

//[In]pRoot: json.
int jsonAnalysisFromJson(json_t* pRoot)
{
    char* pJsonText = NULL;
    char* pEncodeText = NULL;
    char* pSeparateText = NULL;
    int errorCode = 0;
    size_t outputLength = 0;

    if (!pRoot) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s jsonAnalysisFromJson. parameter error.\n",
            JSON_LOG_TAG);
        return JSON_SYSTEM_ERROR;
    }

    pJsonText = json_dumps(pRoot, JSON_ENCODE_ANY | JSON_INDENT(2));
    if (!pJsonText) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s json_dumps error.\n", JSON_LOG_TAG);
        return JSON_SYSTEM_ERROR;
    }

    pEncodeText = CONV_Utf8ToCP437oseString(pJsonText, strlen(pJsonText),
        &errorCode, &outputLength);
    if (!pEncodeText) {
        LOG_PRINTF(DBG_JSON_API_ERROR,
            "%s  jsonAnalysisFromJson. convert string error. errorCode: %d.\n",
            JSON_LOG_TAG, errorCode);
        free(pJsonText);
        return JSON_SYSTEM_ERROR;
    }

    LOG_PRINTF(DBG_JSON_API_INFO, "%s JSON Data: \n", JSON_LOG_TAG);

    pSeparateText = strtok(pEncodeText, "\n");
    LOG_PRINTF(DBG_JSON_API_INFO, "%s %s\n", JSON_LOG_TAG, pSeparateText);

    while (pSeparateText != NULL) {
        pSeparateText = strtok(NULL, "\n");
        LOG_PRINTF(DBG_JSON_API_INFO, "%s %s\n", JSON_LOG_TAG, pSeparateText);
    }
    free(pEncodeText);
    free(pJsonText);

    return JSON_SUCCESS;
}

//[In]pText: text.
int jsonAnalysis(const char* pText)
{
    json_t* pRoot = NULL;
    json_error_t error;
    int result = JSON_SUCCESS;

    if (!pText) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s jsonAnalysis. parameter error.\n",
            JSON_LOG_TAG);
        return JSON_SYSTEM_ERROR;
    }

    pRoot = json_loads(pText, 0, &error);
    if (!pRoot) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s json_loads. error: on line %d: %s\n",
            JSON_LOG_TAG, error.line, error.text);
        return JSON_SYSTEM_ERROR;
    }

    result = jsonAnalysisFromJson(pRoot);
    json_decref(pRoot);

    if (result != JSON_SUCCESS) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s file: %s, line:%d, error.\n",
            JSON_LOG_TAG, __FILE__, __LINE__);
        return JSON_SYSTEM_ERROR;
    }

    return JSON_SUCCESS;
}

//[In]pText
//[Out]pEncodeStr
int getDescriptionFromJson(const char* pText, char* pEncodeStr)
{
    json_t* pRoot = NULL;
    json_error_t error;

    const char* pKey = NULL;
    const char* pKey2 = NULL;
    json_t* pValue = NULL;
    json_t* pValue2 = NULL;
    void* pTemp = NULL;
    void* pTemp2 = NULL;
    char* pUtf8Value = NULL;
    char* pTempValue = NULL;

    int errorCode = 0;
    size_t outputLength = 0;

    pRoot = json_loads(pText, 0, &error);

    if (!pRoot) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s error: on line %d: %s\n",
            JSON_LOG_TAG, error.line, error.text);
        return JSON_SYSTEM_ERROR;
    }

    switch (json_typeof(pRoot)) {
    case JSON_OBJECT:
        json_object_foreach_safe(pRoot, pTemp, pKey, pValue) {
            if (strcmp("results", pKey) == 0) {
                size_t index;
                json_t* pArrayValue;

                json_array_foreach(pValue, index, pArrayValue) {
                    json_object_foreach_safe(pArrayValue, pTemp2, pKey2, pValue2) {
                        if (strcmp("Description", pKey2) == 0) {
                            pUtf8Value = (char*)json_string_value(pValue2);
                            break;
                        }
                    }
                }
                break;
            }
        }
        break;
    default:
        break;
    }

    if (!pUtf8Value) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s pUtf8Value is NULL\n", JSON_LOG_TAG);
        json_decref(pRoot);
        return JSON_SYSTEM_ERROR;
    }

    pTempValue = CONV_Utf8ToCP437oseString((char*)pUtf8Value, strlen(pUtf8Value),
        &errorCode, &outputLength);

    if (!pTempValue) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s errorCode: %d\n", JSON_LOG_TAG, errorCode);
        json_decref(pRoot);
        return JSON_SYSTEM_ERROR;
    }
    else {
        strcpy(pEncodeStr, pTempValue);
    }
    free(pTempValue);
    json_decref(pRoot);

    return JSON_SUCCESS;
}

//[Out]pData
//[In]dataSize
size_t getAuthData(char* pData, size_t dataSize)
{
    json_t* pCreatedJson = NULL;

    pCreatedJson = json_object();
    json_object_set_new(pCreatedJson, "username", json_string(AUTH_USER_NAME));
    json_object_set_new(pCreatedJson, "password", json_string(AUTH_PASSWORD));
    json_object_set_new(pCreatedJson, "email", json_string(""));

    char* pAuthData = json_dumps(pCreatedJson, JSON_ENCODE_ANY);

    size_t size = strlen(pAuthData);
    if (dataSize < (size + 1)) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s Buffer size error. Need %ld size.\n",
            JSON_LOG_TAG, size + 1);
        json_decref(pCreatedJson);

        return 0;
    }

    memcpy(pData, pAuthData, size);
    free(pAuthData);
    json_decref(pCreatedJson);

    return size;
}

//[Out]pData
//[In]dataSize
size_t getAuthHeader(char* pData, size_t dataSize) {

    const char AUTH_HEADER[] = "Accept-Encoding: identity\r\n"
        "Content-Type: application/json\r\n";

    size_t size = strlen(AUTH_HEADER);
    if (dataSize < (size + 1)) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s Auth_header. Buffer size error. Need %ld size.\n",
            JSON_LOG_TAG, size + 1);
        return 0;
    }

    memcpy(pData, AUTH_HEADER, size);

    return size;
}

//[In]pText
//[Out]pTokenHeader
//[In]tokenHeaderSize
size_t getTokenHeader(const char* pText, char* pTokenHeader, size_t tokenHeaderSize)
{
    json_error_t error;
    json_t* pResult = json_loads(pText, 0, &error);
    if (pResult == NULL) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s error: on line %d: %s\n",
            JSON_LOG_TAG, error.line, error.text);
        return 0;
    }

    const char* pJsonToken = json_string_value(json_object_get(pResult, "token"));
    if (pJsonToken == NULL) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s Cannot get token.\n", JSON_LOG_TAG);
        json_decref(pResult);
        return 0;
    }

    size_t size = strlen(pJsonToken);
    const size_t bufferSize = 256 + size;

    char* pTempHeader;
    pTempHeader = malloc(bufferSize);
    if (!pTempHeader) {
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s Cannot allocate memory.\n", JSON_LOG_TAG);
        return 0;
    }

    memset(pTempHeader, 0, bufferSize);

    sprintf(pTempHeader, "Accept-Encoding: identity\r\nContent-Type: application/json\r\n"
        "Authorization: JWT %s\r\nConnection: close\r\n",

        pJsonToken);

    size = strlen(pTempHeader);
    if (tokenHeaderSize < (size + 1)) {
        free(pTempHeader);
        json_decref(pResult);
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s Buffer size error.  Need %ld size.\n",
            JSON_LOG_TAG, size + 1);
        return 0;
    }
    memcpy(pTokenHeader, pTempHeader, size);
    free(pTempHeader);
    json_decref(pResult);
    return size;
}

//[Out]pSubmitData
//[In]submitDataSize
//[In]pSetValue
size_t getSubmitData(char* pSubmitData, size_t submitDataSize, char* pSetValue)
{
    json_t* pCreatedJson = NULL;
    json_t* pParameterJson = NULL;
    size_t size = 0;

    char terminalID[8] = { 0 };
    sprintf(terminalID, "%d", GetTerminalId());

    unsigned int nextId = gRequestId + 1;
    if (nextId > 999999)
    {
        nextId = 1;
    }
    gRequestId = nextId;
    char requestId[7] = { 0 };
    sprintf(requestId, "%06d", gRequestId);

    pCreatedJson = json_object();
    json_object_set_new(pCreatedJson, "request_id", json_string(requestId));
    json_object_set_new(pCreatedJson, "request_name", json_string("get item name"));
    json_object_set_new(pCreatedJson, "requester", json_string("demo"));
    pParameterJson = json_object();
    json_object_set_new(pParameterJson, "username", json_string(AUTH_USER_NAME));
    json_object_set_new(pParameterJson, "terminal_id", json_string(terminalID));
    json_object_set_new(pParameterJson, "barcode", json_string(pSetValue));
    json_object_set_new(pParameterJson, "language_code", json_string("en"));
    json_object_set_new(pCreatedJson, "request_param", pParameterJson);

    char* getItemNameJson = json_dumps(pCreatedJson, JSON_ENCODE_ANY);
    size = strlen(getItemNameJson);

    if (submitDataSize < (size + 1)) {
        free(getItemNameJson);
        LOG_PRINTF(DBG_JSON_API_ERROR, "%s Buffer length error.\n", JSON_LOG_TAG);
        json_decref(pParameterJson);
        json_decref(pCreatedJson);
        return 0;
    }
    memcpy(pSubmitData, getItemNameJson, size);
    free(getItemNameJson);

    json_decref(pParameterJson);
    json_decref(pCreatedJson);
    return size;
}

See also

Last updated: 2023/06/06