chapter 05-02

使用方式 (用戶端)

此章節說明如何在用戶端程式使用 mcm_lulib_run 傳遞資料給內部模組以及從內部模組回傳資料.


範例程式

外部程式部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "mcm_lib/mcm_lulib/mcm_lulib_api.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int main(
    int argc,
    char **argv)
{
    char *path1;
    struct mcm_lulib_lib_t self_lulib;
    char req_data1[128], *rep_data1;
    MCM_DTYPE_USIZE_TD req_len1, rep_len1;
    int req_data2[4], *rep_data2;
    MCM_DTYPE_USIZE_TD req_len2, rep_len2, idx, count;

    srand(time(NULL));

    self_lulib.socket_path = "@mintcm";
    self_lulib.call_from = MCM_CFROM_USER;
    self_lulib.session_permission = MCM_SPERMISSION_RO;
    self_lulib.session_stack_size = 0;
    if(mcm_lulib_init(&self_lulib) < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_init() fail");
        goto FREE_01;
    }

    // 測試-01 : 字串類型資料.

    path1 = "mcm_module_user_data_test_01";
    DMSG("[run] %s", path1);

    snprintf(req_data1, sizeof(req_data1), "user-data-%u", rand());
    req_len1 = strlen(req_data1) + 1;
    DMSG("send [" MCM_DTYPE_USIZE_PF "][%s]", req_len1, req_data1);

    if(mcm_lulib_run(&self_lulib, path1, &req_data1, req_len1, (void **) &rep_data1, &rep_len1)
                     < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

    DMSG("recv [" MCM_DTYPE_USIZE_PF "][%s]", rep_len1, rep_data1);
    free(rep_data1);

    // 測試-02 : 字節類型資料.

    path1 = "mcm_module_user_data_test_02";
    DMSG("[run] %s", path1);

    count = sizeof(req_data2) / sizeof(int);
    for(idx = 0; idx < count; idx++)
        req_data2[idx] = rand() % 100;

    req_len2 = sizeof(req_data2);

    DMSG("send [" MCM_DTYPE_USIZE_PF "] (" MCM_DTYPE_USIZE_PF ") -", req_len2, count);
    for(idx = 0; idx < count; idx++)
    {
        DMSG("%d", req_data2[idx]);
    }

    if(mcm_lulib_run(&self_lulib, path1, &req_data2, req_len2, (void **) &rep_data2, &rep_len2)
                     < MCM_RCODE_PASS)
    {
        DMSG("call mcm_lulib_run(%s) fail", path1);
        goto FREE_02;
    }

    count = rep_len2 / sizeof(int);
    DMSG("recv [" MCM_DTYPE_USIZE_PF "] (" MCM_DTYPE_USIZE_PF ") -", rep_len2, count);
    for(idx = 0; idx < count; idx++)
    {
        DMSG("%d", rep_data2[idx]);
    }
    free(rep_data2);

FREE_02:
    mcm_lulib_exit(&self_lulib);
FREE_01:
    return 0;
}

內部模組部分

#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mcm_lib/mcm_lheader/mcm_type.h"
#include "mcm_lib/mcm_lheader/mcm_size.h"
#include "mcm_lib/mcm_lheader/mcm_control.h"
#include "mcm_lib/mcm_lheader/mcm_connect.h"
#include "mcm_lib/mcm_lheader/mcm_return.h"
#include "mcm_lib/mcm_lheader/mcm_debug.h"
#include "mcm_lib/mcm_lheader/mcm_data_exinfo_auto.h"
#include "../mcm_service_handle_define.h"
#include "../mcm_config_handle_extern.h"

#define DMSG(msg_fmt, msgs...) printf("%s(%04u): " msg_fmt "\n", __FILE__, __LINE__, ##msgs)

int mcm_module_user_data_test_01(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    MCM_DTYPE_USIZE_TD tmp_len;
    char *tmp_buf;

    DMSG("string data test :");

    srand(time(NULL));

    // 外部程式傳來的資料.

    DMSG("recv [" MCM_DTYPE_USIZE_PF "][%s]",
         this_session->req_data_len, (char *) this_session->req_data_con);

    // 內部模組要回傳的資料.

    tmp_len = 256;
    tmp_buf = (char *) malloc(tmp_len);
    if(tmp_buf == NULL)
    {
        DMSG("call malloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }

    snprintf(tmp_buf, tmp_len, "internal data %u", rand());
    tmp_len = strlen(tmp_buf) + 1;
    DMSG("send [" MCM_DTYPE_USIZE_PF "][%s]", tmp_len, tmp_buf);

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

    fret = MCM_RCODE_PASS;
FREE_01:
    return fret;
}

int mcm_module_user_data_test_02(
    struct mcm_service_session_t *this_session)
{
    int fret = MCM_RCODE_MODULE_INTERNAL_ERROR;
    MCM_DTYPE_USIZE_TD tmp_len, idx, count;
    int *tmp_buf;

    DMSG("bytes data test :");

    srand(time(NULL));

    // 外部程式傳來的資料.

    tmp_buf = (int *) this_session->req_data_con;
    count = this_session->req_data_len / sizeof(int);
    DMSG("recv [" MCM_DTYPE_USIZE_PF "] (" MCM_DTYPE_USIZE_PF ") -",
         this_session->req_data_len, count);
    for(idx = 0; idx < count; idx++)
    {
        DMSG("%d", tmp_buf[idx]);
    }

    // 內部模組要回傳的資料.

    count = 6;
    tmp_buf = calloc(count, sizeof(int));
    if(tmp_buf == NULL)
    {
        DMSG("call calloc() fail [%s]", strerror(errno));
        goto FREE_01;
    }
    tmp_len = sizeof(int) * count;

    for(idx = 0; idx < count; idx++)
        tmp_buf[idx] = rand() % 10;

    DMSG("send [" MCM_DTYPE_USIZE_PF "] (" MCM_DTYPE_USIZE_PF ") -", tmp_len, count);
    for(idx = 0; idx < count; idx++)
    {
        DMSG("%d", tmp_buf[idx]);
    }

    this_session->rep_data_buf = tmp_buf;
    this_session->rep_data_len = tmp_len;

    fret = MCM_RCODE_PASS;

FREE_01:
    return fret;
}



範例程式的使用

01.  範例程式目錄在 mint_cm/usage/example/0502.


02.  下面關於 make 的操作沒有特別註明的話都是在 mint_cm 目錄.


03.  第一次使用, 使用 make example_add KEY=0502 載入範例並編譯.


04.  user_app/user_app_0502 是範例程式,
必須先在目錄內使用 make all 進行編譯.

執行 user_app_0502 不需要參數就可測試.


05.  先執行 mcm_daemon, 才可以使用 user_app_0502 做測試.


06.  測試完畢不使用後, 使用 make example_del KEY=0502 將範例移除.


07.  範例程式目錄下的檔案在做完 make example_add 後會複製到真正使用的位置, 要修改做測試的話要改在複製後的.
來源 profile/mcm_data_profile_0502.xml
目地 mint_cm/mcm_build/mcm_data_profile.xml
資料模型範例
有修改要使用 make all 重新編譯
來源 profile/mcm_store_profile_default_0502.txt
目地 mint_cm/mcm_build/mcm_store_profile_default.txt
資料預設值範例
使用 make all 後會再複製到 mint_cm/run
來源 module/mcm_module_0502.c
目地 mint_cm/mcm_daemon/mcm_module
內部模組範例
有修改要使用 make all 重新編譯