RapidSecs的C++基础库包括:
文件 |
描述 |
rapid_secs.h |
头文件 |
RapidSecs.dll |
动态库 |
RapidSecs.lib |
动态库对应的Lib |
主要是定义了一些基本的数据结构和接口函数供用户调用,接口功能在上一章的博文中已经进行了介绍,这里就不再重复了。头文件的代码如下:
程序启动时首先由用户选择是作为主机端?还是作为设备端?然后进一步由用户选择是采用主动模式?还是被动模式?代码如下:
hint00:
unsigned char modeHE = 0;
bool bHost = true;
cout << "Choose mode, Host or Equipment? (Enter H or E): " << endl;
cin >> modeHE;
if (modeHE == 'H' || modeHE == 'h') {
bHost = true;
}
else if (modeHE == 'E' || modeHE == 'e') {
bHost = false;
}
else {
goto hint00;
}
hint01:
unsigned char mode = 0;
cout << "Choose HSMS mode, Passive or Active? (Enter P or A): " << endl;
cin >> mode;
if (mode == 'P' || mode == 'p') {
mode = HSMS_PASSIVE;
}
else if (mode == 'A' || mode == 'a') {
mode = HSMS_ACTIVE;
}
else {
goto hint01;
}
首先,程序要运行需要传入一些基本的配置信息,除上边的运行模式、HSMS模式外还应包括:本机IP/Port、远程IP/Port、设备ID和几个特定的超时等。代码如下:
此处最重要的是几个回调函数如下:
BOOL WINAPI OnConnect(
RSECSH hServer,
RSECSH hSecs,
USHORT usDevId)
{
g_eq_ptr->hsms_session = hSecs;
cout << "Host connected." << endl;
return TRUE;
}
连接建立时调用,保存好句柄,并打印连接成功信息。
DWORD WINAPI OnRecvMessage(
RSECSH session_handle,
unsigned long id,
unsigned char stream,
unsigned char function,
RAPID_SECS_ITEM* ptr_item)
{
secs_log::secs_log_msg_to_console(id, stream, function, ptr_item);
// process message
return proc_result;
}
接收到消息后触发的回调,后面所有对接收到消息的处理都要基于此回调函数。
VOID WINAPI OnClose(
RSECSH hSecs)
{
g_eq_ptr->hsms_session = NULL;
cout << "Host disconnected." << endl;
}
连接断开时的回调函数,示例仅打印信息。
void WINAPI OnReplyTimeout(
RSECSH session_handle,
unsigned long id)
{
cout << "message[" << id << "] reply timeout" << endl;
if (g_eq_ptr->m_comm_fsm.m_msgid_s1f13 == id) {
comm_fsm_send_event(&(g_eq_ptr->m_comm_fsm), gem_impl::RECV_S1_F14_TIMEOUT);
}
}
当之前发送的消息在T3时间内没收到回应时,RapidSecs库触发此回调。示例仅打印信息。
然后,就是根据配置信息开启服务,那么无论是主机端还是设备端首先都要调用“rapid_create_secs”创建secs对象,再根据是主动模式?还是被动模式来决定是调用“rapid_secs_startup_server”?还是“rapid_secs_connect”,主要的代码如下:
int start_gem_service(gem_impl::GEM_EQUIPMENT* eq, RAPID_SECS_CFG* settings)
{
eq->m_comm_fsm.state = gem_impl::DISABLED;
eq->server_handle = NULL;
eq->active_handle = NULL;
eq->hsms_session = NULL;
start_comm_fsm(eq);
comm_fsm_send_event(&eq->m_comm_fsm, gem_impl::EV_ENABLE_COMM);
RSECSH secs_inst = rapid_create_secs(settings);
if (secs_inst == NULL) {
cout << "rapid_create_secs failed." << endl;
return E_FAILED;
}
BOOL start_up_ok = false;
switch(settings->mode) {
case HSMS_PASSIVE: {
start_up_ok = rapid_secs_startup_server(secs_inst);
if (!start_up_ok) {
cout << "rapid_secs_startup_server failed." << endl;
rapid_destroy_secs(secs_inst);
return E_FAILED;
}
else {
cout << "SIM equipment started, PASSIVE mode." << endl;
eq->server_handle = secs_inst;
}
}
break;
case HSMS_ACTIVE: {
cout << "start SIM equipment in ACTIVE mode." << endl;
start_up_ok = rapid_secs_connect(secs_inst);
if (start_up_ok) {
g_eq_ptr->hsms_session = secs_inst;
cout << "connect OK." << endl;
}
else {
cout << "connect failed. RapidSecs will retry after T7 time..." << endl;
}
g_eq_ptr->active_handle = secs_inst;
}
break;
default:
break;
}
return E_SUCCESS;
}
初始化完成之后的下一步就是要建立连接,然后才能进行下一步的通讯过程。当使用测试工具与Demo程序建立连接时,OnConnect将会被调用,如下图所示:
到此,主机端和设备端Demo已经能够建立连接了,但是还不能建立真正的有效通信,因为建立连接后由于Demo程序是设备端被动模式,而测试工具是主机端主动模式,所以在建立连接后主机端会主动发送S1F13命令请求与设备端建立通信,而设备端Demo则回复S1F14命令进行确认,而设备端目前还不具备状态机、数据接收处理和数据组装功能,还无法响应S1F13命令。