RESTful API サンプルプログラムです。

  • 本サンプル用のデモサイトが用意されています。
  • 本サンプルを使用するにはデモサイトにお客様用のアカウントを作成していただくと、本サンプルでバーコードを読取後、RESTful API(JSON形式)でWifi経由でやり取りを行い、バーコードの商品名をOPH上に表示することができます。
  • デモサイトとのインターフェース(RESTful API)の仕様は下記を参照してください。
  • まず、次のURLにJWT(JSON Web Token)で、JSONをベースとしたトークン認証を行います。

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

    その後、OPH側で次のURLにJSON 形式で要求をPOSTし、JSON形式の応答を受信します。

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

    大まかな流れを下記に記載します。

    1. [OPH] ユーザ認証を要求する
    2. [デモサーバー] 認証OKならトークンを返す
    3. [OPH] トークンをAPIの内部に付加して要求する
    4. [デモサーバー] APIの結果を返す

    下記は、POSTの時のextra headerとbodyの説明になります。上記の番号と連動しています。2の[トークン]には、デモサーバーから取得した文字列が入ります。3の[トークン]には、2の[トークン]をセットします。さらに詳しく知りたい場合は、[RFC7519] JSON Web Token (JWT)を参照してください。

    番号 タイプ 説明
    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": "[トークン]"}
    3 Request extra header "Accept-Encoding: identity\r\nContent-Type: application/json\r\nAuthorization: JWT [トークン]\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": "ja"
      }
    }
    
    4 Response body
    {
      "request_id": "000001",
      "request_name": "get item name",
      "requester": "demo",
      "request_param": {
        "username": "XXXXXXXXXX",
        "terminal_id": "7890",
        "barcode": "4902102072618",
        "language_code": "ja"
      },
      "results": [
        {
          "Barcode": "4902102072618",
          "Description": "コカ・コーラ 500ml"
        }
      ],
      "status": "000"
    }
    

    RESTful APIのJSON形式で指定する変数名と値は次のとおりです。

    変数 説明
    request_id リクエストの連番
    request_name リクエスト名
    requester リクエスト元
    request_param JSON形式のリクエストパラメーター
    username ユーザ名
    terminal_id 端末ID
    barcode 読み取ったバーコード
    language_code 商品名、表記言語
    "ja": 日本語
    "en": 英語
    results JSON形式の応答
    Barcode 応答のバーコード
    Description 応答のバーコードの商品名
    status API の実行結果
    "000": 正常終了
    "004": 対象バーコードがサーバーに未登録
    "501": API のパラメータ異常
    "999": サーバー設定異常

 本サンプルに使用するには、次のライブラリをアプリケーションプログラムにリンクしてください。

ヘッダファイル:
lib.h : システム18.0以降
http_request.h
jansson.h
jansson_config.h
jansson_log.h
CodeConversion.h : ver.1.1.1以降
AdvancedMenu.h
ライブラリファイル:
libHttpRequest.a
libJansson.a
libCodeConversion.a : ver.1.1.1以降
libAdvancedMenu.a
libSTARTUPOPH5000.a : システム18.0以降

(注意)

 ライブラリファイルの追加を行うときは上記の順番に合わせてリンクしてください。

手順

 1. アカウントを新規作成します。

 2. 先ほど作成したアカウントでログインします。

 3. JSONデモのページを開きます。

 4. サンプルコードjsonRequest.cに関して、AUTH_USER_NAMEとAUTH_PASSWORDのdefineを作成したアカウントに変更してください。

 5. 本サンプルアプリでバーコードを読み取ります。

 6. OPH5000iの画面上に商品名が表示されます。



サンプル: 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;
}


サンプル: 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_ */

サンプル: 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/ja/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_Utf8ToSjisString(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_Utf8ToSjisString((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("ja"));
    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;
}

関連事項

最終更新日:2023/06/06