National standard GB28181 protocol client development (2) program structure and registration

National standard GB28181 protocol client development (2) program structure and registration

This series of articles aims to explore the development process of the device side of the national standard GB28181 protocol. This article will focus on architecture design and device registration, and introduce in detail the program architecture design, exosip library introduction and interface classification on the device side, as well as the registration process and signaling interaction messages on the GB28181 device side. By reading this article, readers will have an in-depth understanding of the architectural design principles of the device side of the GB28181 protocol, how to use the exosip library, as well as the device registration process and key messages for signaling interaction.

1. Program architecture design

In the development of the device side of the GB28181 protocol, good program architecture design is the basis for ensuring system stability and scalability. We can consider the following aspects:

  1. Layered architecture: Divide the device-side functions into different layers, such as media layer, control layer, storage layer, network layer, etc., to achieve modular development and maintenance.

  2. Module design: According to functional requirements, the device is divided into different modules, such as platform access module, media parsing module, encoding module, decoding module, etc. Each module is responsible for specific functions, interacting and communicating through interfaces.

  3. Data structure design: The GB28181 protocol involves rich data structures, such as device information, media streams, signaling messages, etc. When designing a data structure, it is necessary to consider data organization and access efficiency, as well as compatibility with protocol specifications.

The following is the program framework for developing the device side of the GB28181 protocol:

Insert image description here

2. Introduction to exosip library and interface classification

eXosip is an extension library based on the oSIP library, used to implement the development of SIP protocols. It provides an event-driven programming interface for processing SIP signaling and implementing SIP applications, and is widely used in the development of GB28181 device side. It provides rich interfaces and functions to simplify the development process. Here is an overview of eXosip’s internal architecture:

Insert image description here

  1. SIP Context:
    The eXosip library uses SIP context to manage and process SIP sessions. Each SIP context has a unique ID, and the context can be created through the function eXosip_malloc(). Applications can create multiple contexts to handle different SIP sessions.

  2. Event Loop:
    The eXosip library processes received SIP messages and events through the event loop mechanism. The event loop will continue to listen to the network socket, waiting for the arrival of SIP messages or the triggering of timer events. When an event occurs, the eXosip library will generate the corresponding event and put it into the event queue waiting for processing.

  3. Event Handler:
    The eXosip library provides a set of event handler functions for handling various types of events, such as registration, call invitations, message sending and receiving, etc. Applications can register corresponding event handler functions as needed and execute custom logic when events occur.

  4. SIP Message Handler:
    The eXosip library provides a set of functions to process SIP messages, including parsing and constructing SIP requests and responses. It uses the low-level functionality of the oSIP library to handle the parsing and assembly of SIP messages and provides a higher-level interface for application use.

  5. Network Communication:
    The eXosip library uses underlying network sockets for SIP communication. It provides functions for interacting with the network layer, such as creating and binding sockets, sending and receiving SIP messages, etc. Applications can configure and manage network communication-related parameters as needed.

The internal architecture of the eXosip library makes full use of the underlying functions provided by the oSIP library and provides higher-level interfaces and event-driven programming models, making it easier for developers to implement SIP-based applications.

The interfaces of the exosip library can be divided into the following categories:

  1. Initialization and configuration interface: including library initialization, setting SIP protocol stack parameters, configuring listening ports, etc.

  2. Registration and deregistration interface: used for device registration and deregistration operations, including sending and receiving processing of registration requests.

  3. Signaling interaction interface: used to send and receive SIP signaling messages, such as call invitations, media flow control, etc.

3. exosip initialization and message loop

Before using the exosip library, initialization and configuration operations are required. Specific steps are as follows:

  1. Initialize the exosip library: call the initialization interface, initialize the exosip library, and set some global parameters.

  2. Configure the SIP protocol stack: Set the relevant parameters of the SIP protocol stack, such as IP address, port, etc., by configuring the interface.

  3. Create a SIP context: Use the context interface to create a SIP context for subsequent registration and signaling interaction operations.

#include <osip2/osip.h>
#include <eXosip2/eXosip.h>


// 初始化eXosip和osip栈
exosip_ = eXosip_malloc();
ret_code = eXosip_init(exosip_);
if (ret_code != OSIP_SUCCESS)
{
   SIMPLE_LOG("Can't initialize eXosip!");
   exit(1);
}

// 配置exosip库参数,如IP地址和端口
ret_code = eXosip_listen_addr(exosip_, IPPROTO_UDP, NULL, cfg_.sip_local_port, AF_INET, 0);
if (ret_code != OSIP_SUCCESS)
{
   SIMPLE_LOG("eXosip_listen_addr error!");

   eXosip_quit(exosip_);

   exit(1);
}

eXosip_set_user_agent(exosip_, "HbsGBSIP-1.0");

// 发送初始注册报文
SipSendRegister(false, nullptr);

// 接收和处理SIP报文
while (!is_need_stop_)
{
   // 处理事件
   eXosip_event_t* sip_event = eXosip_event_wait(exosip_, 0, 10);

   // 一般处理401/407采用库默认处理
   eXosip_lock(exosip_);
   eXosip_default_action(exosip_, sip_event);
   eXosip_unlock(exosip_);

   // 超时
   if (sip_event == NULL)
   {
      continue;
   }

   // 尝试解析报文头部信息
   OSipMsgParser msg_parser;
   if (sip_event->request)
   {
      msg_parser.ParseHeader(sip_event->request);
   }

   switch (sip_event->type)
   {
      case EXOSIP_REGISTRATION_SUCCESS: {
         // 注册成功处理
         break;
      }
      case EXOSIP_REGISTRATION_FAILURE: {
         // 注册失败处理
         break;
      }
      case EXOSIP_MESSAGE_NEW: {
         // 收到新的SIP消息处理
         if (sip_event->request) {
            // 处理请求消息
            osip_message_t* request = sip_event->request;
            // 解析和处理请求消息
         } else if (sip_event->response) {
            // 处理响应消息
            osip_message_t* response = sip_event->response;
            // 解析和处理响应消息
         }
         break;
      }
      case EXOSIP_CALL_INVITE: {
         // 收到呼叫邀请处理
         // 解析和处理呼叫邀请消息
         break;
      }
      // 其他事件处理...

      default:
         break;
      }

   // 释放事件
   eXosip_event_free(sip_event);
}


// 清理exosip库资源
eXosip_quit(exosip_);
osip_free(exosip_);
exosip_ = NULL;

4. Signaling interaction messages during the GB28181 registration process

Insert image description here

The registration process is described below:

  1. The SIP proxy sends a Register request to the SIP server;


  2. The SIP server sends a response 401 to the SIP proxy, and gives the authentication system and parameters suitable for the SIP proxy in the WWW_Authenticate field of the response header ;

  3. The SIP proxy resends the Register request to the SIP server, giving a certificate of trust and
    including authentication information in the Authorization field of the request;

  4. The SIP server verifies the request. If the identity of the SIP proxy is checked to be legitimate, a success response of
    200OK is sent to the SIP proxy. If the identity is not legitimate, a denial of service response is sent.

After WireShark intercepts the packet, you can see:

Insert image description here

  1. Register for the first time:
REGISTER sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.54:10561;rport;branch=z9hG4bK639602844
From: <sip:[email protected]:10561>;tag=91827836
To: <sip:[email protected]:10561>
Call-ID: 2847584547
CSeq: 1 REGISTER
Contact: <sip:[email protected]:10561;line=00c3a618be4c249>
Max-Forwards: 70
User-Agent: HbsGBSIP-1.0
Expires: 3600
Content-Length: 0
  1. GB28181 platform returns 401 error:
SIP/2.0 401 Unauthorized
Via: SIP/2.0/UDP 192.168.1.54:10561;rport;branch=z9hG4bK639602844
From: <sip:[email protected]:10561>;tag=91827836
To: <sip:[email protected]:10561>;tag=1724123124
Call-ID: 2847584547
CSeq: 1 REGISTER
WWW-Authenticate: Digest realm="34020000", nonce="awer23sdfj123123", opaque="c3a02f1ecb122d255c4ae2266129d044", algorithm=MD5
User-Agent: General
Content-Length: 0
  1. After adding the authentication information, send the registration message for the second time:
REGISTER sip:[email protected]:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.1.54:10561;rport;branch=z9hG4bK2311457380
From: <sip:[email protected]:10561>;tag=91827836
To: <sip:[email protected]:10561>
Call-ID: 2847584547
CSeq: 0 REGISTER
Contact: <sip:[email protected]:10561;line=00c3a618be4c249>
Authorization: Digest username="34020000001110000002", realm="34020000", nonce="awer23sdfj123123", uri="sip:[email protected]:5060", response="dc953f5c48a92517ff6542ef6cd97e20", algorithm=MD5, opaque="c3a02f1ecb122d255c4ae2266129d044"
Max-Forwards: 70
User-Agent: HbsGBSIP-1.0
Expires: 3600
Content-Length: 0
  1. The GB28181 platform returns 200 registration successful:
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.54:10561;rport;branch=z9hG4bK2311457380
From: <sip:[email protected]:10561>;tag=91827836
To: <sip:[email protected]:10561>;tag=31243r3412
Call-ID: 2847584547
CSeq: 0 REGISTER
User-Agent: General
Date: 2023-03-15T16:18:33
Expires: 300
Content-Length: 0

The code for calling eXosip to register is as follows:

osip_message_t* reg = nullptr;

SIMPLE_LOG("new build register\n");

std::string from_str = MakeSIPFromToStr(cfg_.sip_local_device_id,
   cfg_.sip_local_ip, cfg_.sip_local_port);
std::string to_str = MakeSIPFromToStr(cfg_.sip_server_id,
      cfg_.sip_server_ip, cfg_.sip_server_port);

register_id_ = eXosip_register_build_initial_register(exosip_,
   from_str.c_str(),   //"sip:[email protected]:7777",
   to_str.c_str(),     //"sip:[email protected]:5060",
   NULL, expire_val, &reg);

auto ret = eXosip_register_send_register(exosip_, register_id_, reg);

]

Please add the author hbstream ( http://haibindev.cnblogs.com ) for cooperation. Please indicate the author and source when reprinting.

Guess you like

Origin blog.csdn.net/haibindev/article/details/131380985