mirror of
https://github.com/apache/nuttx-apps.git
synced 2025-10-20 04:26:04 +08:00

This commit adds CMUX (GSM 07.10) protocol support to netutils. CMUX allows multiplexing multiple virtual serial connections over a single physical serial link. Changes include: - CMUX protocol implementation - CRC table for frame validation - Basic frame handling Signed-off-by: Halysson <halysson1007@gmail.com>
233 lines
7.6 KiB
C
233 lines
7.6 KiB
C
/****************************************************************************
|
|
* apps/netutils/cmux/cmux.h
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed with
|
|
* this work for additional information regarding copyright ownership. The
|
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
* License for the specific language governing permissions and limitations
|
|
* under the License.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#ifndef __APPS_NETUTILS_CMUX_H
|
|
#define __APPS_NETUTILS_CMUX_H
|
|
|
|
/****************************************************************************
|
|
* Included Files
|
|
****************************************************************************/
|
|
|
|
#include <sys/time.h>
|
|
#include <stdbool.h>
|
|
#include <debug.h>
|
|
#include <errno.h>
|
|
|
|
#define CMUX_BIT0 (0)
|
|
#define CMUX_BIT1 (1)
|
|
#define CMUX_BIT2 (2)
|
|
#define CMUX_BIT3 (3)
|
|
#define CMUX_BIT4 (4)
|
|
#define CMUX_BIT5 (5)
|
|
#define CMUX_BIT6 (6)
|
|
#define CMUX_BIT7 (7)
|
|
|
|
#define CMUX_BUFFER_SZ (1024)
|
|
#define CMUX_CHANNEL_NAME_SZ (64)
|
|
#define CMUX_FRAME_MAX_SIZE (127)
|
|
|
|
/**
|
|
* Mux Frame
|
|
*
|
|
* | Open flag |
|
|
* | 1 octed |
|
|
* | 0xF9 |
|
|
* ______________________
|
|
* Address
|
|
* | 1 octet |
|
|
* | ---------- |
|
|
* ______________________
|
|
* Control
|
|
* | 1 octet |
|
|
* | ---------- |
|
|
* ______________________
|
|
* Length
|
|
* | 1-2 octet |
|
|
* | --------- |
|
|
* ______________________
|
|
* Information
|
|
* | Multiples octets |
|
|
* | ---------------- |
|
|
* ______________________
|
|
* | FCS |
|
|
* | 1 octed |
|
|
* | --------- |
|
|
* ______________________
|
|
* | Close flag |
|
|
* | 1 octed |
|
|
* | 0xF9 |
|
|
*
|
|
*/
|
|
|
|
/* Flag Field - Each frame begins and ends with a flag sequence octet. */
|
|
|
|
#define CMUX_OPEN_FLAG (0xF9)
|
|
#define CMUX_CLOSE_FLAG (0xF9)
|
|
|
|
/**
|
|
* Address Field
|
|
*
|
|
* |Bit 1 |Bit 2 |Bit 3 |Bit 4 |Bit 5 |Bit 6 |Bit 7 |Bit 8
|
|
* |ADDR_FIELD_BIT_EA | C/R | | | | DLCI | |
|
|
*/
|
|
|
|
/* EA bit extends the range of the address field.
|
|
* When the EA bit is set to 1 in an octet, it signifies that this octet
|
|
* is the last octet of the length field.
|
|
* When the EA bit is set to 0, it signifies that another
|
|
* octet of the address field follows.
|
|
*/
|
|
|
|
#define CMUX_ADDR_FIELD_BIT_EA (CMUX_BIT1)
|
|
#define CMUX_ADDR_FIELD_OPERATOR (0x3F)
|
|
#define CMUX_ADDR_FIELD_CHECK (0xFC)
|
|
|
|
/**
|
|
* The C/R (command/response) bit identifies the frame as
|
|
* either a command or a response.
|
|
* ______________________________
|
|
* ________| Direction| CR Value
|
|
* Command | T.E -> U.E | 1
|
|
* Command | T.E <- U.E | 0
|
|
* ______________________________
|
|
* Response | T.E -> U.E | 1
|
|
* Response | T.E <- U.E | 0
|
|
*/
|
|
|
|
#define CMUX_ADDR_FIELD_BIT_CR (CMUX_BIT2)
|
|
|
|
/* Control field
|
|
* |Bit 1 |Bit 2| Bit 3 |Bit 4 |Bit 5 |Bit 6 |Bit 7 |Bit 8
|
|
* - - - - PF - - -
|
|
* P/F (Poll/Final)
|
|
* - The Poll bit set to 1 shall be used by one station to solicit poll
|
|
* a response or sequence of responses from the other station.
|
|
* - The final bit set to 1 shall be used by a station to indicate
|
|
* the response frame transmitted as the result of a
|
|
* soliciting (poll) command.
|
|
*/
|
|
|
|
/* Poll/Final */
|
|
|
|
#define CMUX_CONTROL_FIELD_BIT_PF (0x10)
|
|
|
|
/* Set Asynchronous Balanced Mode : establish DLC between T.E and U.E */
|
|
|
|
#define CMUX_FRAME_TYPE_SABM (0x2F)
|
|
|
|
/* Unnumbered Acknowledgement: is a response to SABM or DISC frame */
|
|
|
|
#define CMUX_FRAME_TYPE_UA (0x63)
|
|
|
|
/* Disconnected Mode : frame is used to report a status where the station
|
|
* is logically disconnected from the data link. When in disconnected mode,
|
|
* no commands are accepted until the disconnected mode is terminated by
|
|
* the receipt of a SABM command. If a DISC command is received while
|
|
* in disconnected mode, a DM response is sent
|
|
*/
|
|
|
|
#define CMUX_FRAME_TYPE_DM (0x0F)
|
|
|
|
/* Disconnect : is a command frame and is used to close down DLC. */
|
|
|
|
#define CMUX_FRAME_TYPE_DISC (0x43)
|
|
|
|
/* Unnumbered Information with Header check :
|
|
* command/response sends user data at either station
|
|
*/
|
|
|
|
#define CMUX_FRAME_TYPE_UIH (0xEF)
|
|
|
|
/* Unnumbered Information */
|
|
|
|
#define CMUX_FRAME_TYPE_UI (0x03)
|
|
|
|
#define CMUX_FRAME_TYPE(type, frame) ((frame->control & ~CMUX_CONTROL_FIELD_BIT_PF) == type)
|
|
|
|
/* | U.E | <--------- SABM (DLC 1) ------------- | T.E
|
|
* | | ---------- U.A (Response) ------------> |
|
|
* | Multiplexer | <---------- DISC (Close DLC 1) ------------ | Recv
|
|
* | | <----------- UA(Response) ----------- |
|
|
*/
|
|
|
|
/* Note : Some manufactures doesn't support UI frame. */
|
|
|
|
/* Length Field
|
|
* |Bit 1 |Bit 2| Bit 3 |Bit 4 |Bit 5 |Bit 6 |Bit 7 |Bit 8
|
|
* E/A L1 L2 L3 L4 L5 L6 L7
|
|
* - L1 - L7 : The L1 to L7 bits indicate the length of the
|
|
* following data field for the information field less than 128 bytes
|
|
* - EA bit = 1 in an octet, it signifies that this octet
|
|
* is the last octet of the length field.
|
|
* - EA bit = 0, it signifies that a second octet of
|
|
* the length field follows.
|
|
* The total length of the length field is 15 bits in that case.
|
|
*/
|
|
|
|
#define CMUX_LENGTH_FIELD_MAX_VALUE (0x7F)
|
|
#define CMUX_LENGTH_FIELD_OPERATOR (0xFE)
|
|
|
|
/* Information Field
|
|
* The information field is the payload of the frame and carries the
|
|
* user data and any convergence layer information.
|
|
* The field is octet structured and only presents in UIH frames.
|
|
*/
|
|
|
|
/* FSC field
|
|
* In the case of the UIH frame, the contents of the information field shall
|
|
* not be included in the FCS calculation. FCS is calculated on the contents
|
|
* of the address, control and length fields only. This means that only the
|
|
* delivery to the correct DLCI is protected, but not the information.
|
|
*/
|
|
|
|
#define CMUX_FCS_MAX_VALUE (0xFF)
|
|
#define CMUX_FCS_OPERATOR (0xCF)
|
|
struct cmux_parse_s
|
|
{
|
|
unsigned char address; /* Reserved to address filed */
|
|
unsigned char control; /* Reserved to control field */
|
|
int data_length; /* Reserved to data length field */
|
|
unsigned char data[CMUX_BUFFER_SZ]; /* Reserved to information field */
|
|
};
|
|
|
|
struct cmux_stream_buffer_s
|
|
{
|
|
unsigned char data[CMUX_BUFFER_SZ]; /* Buffer to hold incoming packets. */
|
|
unsigned char *readp; /* Pointer to read buffer */
|
|
unsigned char *writep; /* Pointer to write buffer */
|
|
unsigned char *endp; /* Pointer to end of buffer */
|
|
int flag_found; /* Detected open flag */
|
|
unsigned long received_count; /* Counter to received packets */
|
|
unsigned long dropped_count; /* Counter to dropped packets */
|
|
};
|
|
|
|
struct cmux_channel_s
|
|
{
|
|
int master_fd; /* Master pseudo terminal */
|
|
int slave_fd; /* Slave pseudo terminal */
|
|
int dlci; /* Data Link Connection Identifier */
|
|
char slave_path[CMUX_CHANNEL_NAME_SZ]; /* Path do slave (/dev/pts/X) */
|
|
bool active; /* Flag to check if the channel is active */
|
|
time_t last_activity; /* Timestamp to last packet sent/received */
|
|
};
|
|
|
|
#endif /* __APPS_NETUTILS_CMUX_H */ |