162306a36Sopenharmony_ci/* $Id: capiutil.c,v 1.13.6.4 2001/09/23 22:24:33 kai Exp $ 262306a36Sopenharmony_ci * 362306a36Sopenharmony_ci * CAPI 2.0 convert capi message to capi message struct 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * From CAPI 2.0 Development Kit AVM 1995 (msg.c) 662306a36Sopenharmony_ci * Rewritten for Linux 1996 by Carsten Paeth <calle@calle.de> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This software may be used and distributed according to the terms 962306a36Sopenharmony_ci * of the GNU General Public License, incorporated herein by reference. 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <linux/module.h> 1462306a36Sopenharmony_ci#include <linux/string.h> 1562306a36Sopenharmony_ci#include <linux/ctype.h> 1662306a36Sopenharmony_ci#include <linux/stddef.h> 1762306a36Sopenharmony_ci#include <linux/kernel.h> 1862306a36Sopenharmony_ci#include <linux/mm.h> 1962306a36Sopenharmony_ci#include <linux/init.h> 2062306a36Sopenharmony_ci#include <linux/isdn/capiutil.h> 2162306a36Sopenharmony_ci#include <linux/slab.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#include "kcapi.h" 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci/* from CAPI2.0 DDK AVM Berlin GmbH */ 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_citypedef struct { 2862306a36Sopenharmony_ci int typ; 2962306a36Sopenharmony_ci size_t off; 3062306a36Sopenharmony_ci} _cdef; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#define _CBYTE 1 3362306a36Sopenharmony_ci#define _CWORD 2 3462306a36Sopenharmony_ci#define _CDWORD 3 3562306a36Sopenharmony_ci#define _CSTRUCT 4 3662306a36Sopenharmony_ci#define _CMSTRUCT 5 3762306a36Sopenharmony_ci#define _CEND 6 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_cistatic _cdef cdef[] = 4062306a36Sopenharmony_ci{ 4162306a36Sopenharmony_ci /*00 */ 4262306a36Sopenharmony_ci {_CEND}, 4362306a36Sopenharmony_ci /*01 */ 4462306a36Sopenharmony_ci {_CEND}, 4562306a36Sopenharmony_ci /*02 */ 4662306a36Sopenharmony_ci {_CEND}, 4762306a36Sopenharmony_ci /*03 */ 4862306a36Sopenharmony_ci {_CDWORD, offsetof(_cmsg, adr.adrController)}, 4962306a36Sopenharmony_ci /*04 */ 5062306a36Sopenharmony_ci {_CMSTRUCT, offsetof(_cmsg, AdditionalInfo)}, 5162306a36Sopenharmony_ci /*05 */ 5262306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, B1configuration)}, 5362306a36Sopenharmony_ci /*06 */ 5462306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, B1protocol)}, 5562306a36Sopenharmony_ci /*07 */ 5662306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, B2configuration)}, 5762306a36Sopenharmony_ci /*08 */ 5862306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, B2protocol)}, 5962306a36Sopenharmony_ci /*09 */ 6062306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, B3configuration)}, 6162306a36Sopenharmony_ci /*0a */ 6262306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, B3protocol)}, 6362306a36Sopenharmony_ci /*0b */ 6462306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, BC)}, 6562306a36Sopenharmony_ci /*0c */ 6662306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, BChannelinformation)}, 6762306a36Sopenharmony_ci /*0d */ 6862306a36Sopenharmony_ci {_CMSTRUCT, offsetof(_cmsg, BProtocol)}, 6962306a36Sopenharmony_ci /*0e */ 7062306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, CalledPartyNumber)}, 7162306a36Sopenharmony_ci /*0f */ 7262306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, CalledPartySubaddress)}, 7362306a36Sopenharmony_ci /*10 */ 7462306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, CallingPartyNumber)}, 7562306a36Sopenharmony_ci /*11 */ 7662306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, CallingPartySubaddress)}, 7762306a36Sopenharmony_ci /*12 */ 7862306a36Sopenharmony_ci {_CDWORD, offsetof(_cmsg, CIPmask)}, 7962306a36Sopenharmony_ci /*13 */ 8062306a36Sopenharmony_ci {_CDWORD, offsetof(_cmsg, CIPmask2)}, 8162306a36Sopenharmony_ci /*14 */ 8262306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, CIPValue)}, 8362306a36Sopenharmony_ci /*15 */ 8462306a36Sopenharmony_ci {_CDWORD, offsetof(_cmsg, Class)}, 8562306a36Sopenharmony_ci /*16 */ 8662306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, ConnectedNumber)}, 8762306a36Sopenharmony_ci /*17 */ 8862306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, ConnectedSubaddress)}, 8962306a36Sopenharmony_ci /*18 */ 9062306a36Sopenharmony_ci {_CDWORD, offsetof(_cmsg, Data)}, 9162306a36Sopenharmony_ci /*19 */ 9262306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, DataHandle)}, 9362306a36Sopenharmony_ci /*1a */ 9462306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, DataLength)}, 9562306a36Sopenharmony_ci /*1b */ 9662306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, FacilityConfirmationParameter)}, 9762306a36Sopenharmony_ci /*1c */ 9862306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, Facilitydataarray)}, 9962306a36Sopenharmony_ci /*1d */ 10062306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, FacilityIndicationParameter)}, 10162306a36Sopenharmony_ci /*1e */ 10262306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, FacilityRequestParameter)}, 10362306a36Sopenharmony_ci /*1f */ 10462306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, FacilitySelector)}, 10562306a36Sopenharmony_ci /*20 */ 10662306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, Flags)}, 10762306a36Sopenharmony_ci /*21 */ 10862306a36Sopenharmony_ci {_CDWORD, offsetof(_cmsg, Function)}, 10962306a36Sopenharmony_ci /*22 */ 11062306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, HLC)}, 11162306a36Sopenharmony_ci /*23 */ 11262306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, Info)}, 11362306a36Sopenharmony_ci /*24 */ 11462306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, InfoElement)}, 11562306a36Sopenharmony_ci /*25 */ 11662306a36Sopenharmony_ci {_CDWORD, offsetof(_cmsg, InfoMask)}, 11762306a36Sopenharmony_ci /*26 */ 11862306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, InfoNumber)}, 11962306a36Sopenharmony_ci /*27 */ 12062306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, Keypadfacility)}, 12162306a36Sopenharmony_ci /*28 */ 12262306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, LLC)}, 12362306a36Sopenharmony_ci /*29 */ 12462306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, ManuData)}, 12562306a36Sopenharmony_ci /*2a */ 12662306a36Sopenharmony_ci {_CDWORD, offsetof(_cmsg, ManuID)}, 12762306a36Sopenharmony_ci /*2b */ 12862306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, NCPI)}, 12962306a36Sopenharmony_ci /*2c */ 13062306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, Reason)}, 13162306a36Sopenharmony_ci /*2d */ 13262306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, Reason_B3)}, 13362306a36Sopenharmony_ci /*2e */ 13462306a36Sopenharmony_ci {_CWORD, offsetof(_cmsg, Reject)}, 13562306a36Sopenharmony_ci /*2f */ 13662306a36Sopenharmony_ci {_CSTRUCT, offsetof(_cmsg, Useruserdata)} 13762306a36Sopenharmony_ci}; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_cistatic unsigned char *cpars[] = 14062306a36Sopenharmony_ci{ 14162306a36Sopenharmony_ci /* ALERT_REQ */ [0x01] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01", 14262306a36Sopenharmony_ci /* CONNECT_REQ */ [0x02] = "\x03\x14\x0e\x10\x0f\x11\x0d\x06\x08\x0a\x05\x07\x09\x01\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01", 14362306a36Sopenharmony_ci /* DISCONNECT_REQ */ [0x04] = "\x03\x04\x0c\x27\x2f\x1c\x01\x01", 14462306a36Sopenharmony_ci /* LISTEN_REQ */ [0x05] = "\x03\x25\x12\x13\x10\x11\x01", 14562306a36Sopenharmony_ci /* INFO_REQ */ [0x08] = "\x03\x0e\x04\x0c\x27\x2f\x1c\x01\x01", 14662306a36Sopenharmony_ci /* FACILITY_REQ */ [0x09] = "\x03\x1f\x1e\x01", 14762306a36Sopenharmony_ci /* SELECT_B_PROTOCOL_REQ */ [0x0a] = "\x03\x0d\x06\x08\x0a\x05\x07\x09\x01\x01", 14862306a36Sopenharmony_ci /* CONNECT_B3_REQ */ [0x0b] = "\x03\x2b\x01", 14962306a36Sopenharmony_ci /* DISCONNECT_B3_REQ */ [0x0d] = "\x03\x2b\x01", 15062306a36Sopenharmony_ci /* DATA_B3_REQ */ [0x0f] = "\x03\x18\x1a\x19\x20\x01", 15162306a36Sopenharmony_ci /* RESET_B3_REQ */ [0x10] = "\x03\x2b\x01", 15262306a36Sopenharmony_ci /* ALERT_CONF */ [0x13] = "\x03\x23\x01", 15362306a36Sopenharmony_ci /* CONNECT_CONF */ [0x14] = "\x03\x23\x01", 15462306a36Sopenharmony_ci /* DISCONNECT_CONF */ [0x16] = "\x03\x23\x01", 15562306a36Sopenharmony_ci /* LISTEN_CONF */ [0x17] = "\x03\x23\x01", 15662306a36Sopenharmony_ci /* MANUFACTURER_REQ */ [0x18] = "\x03\x2a\x15\x21\x29\x01", 15762306a36Sopenharmony_ci /* INFO_CONF */ [0x1a] = "\x03\x23\x01", 15862306a36Sopenharmony_ci /* FACILITY_CONF */ [0x1b] = "\x03\x23\x1f\x1b\x01", 15962306a36Sopenharmony_ci /* SELECT_B_PROTOCOL_CONF */ [0x1c] = "\x03\x23\x01", 16062306a36Sopenharmony_ci /* CONNECT_B3_CONF */ [0x1d] = "\x03\x23\x01", 16162306a36Sopenharmony_ci /* DISCONNECT_B3_CONF */ [0x1f] = "\x03\x23\x01", 16262306a36Sopenharmony_ci /* DATA_B3_CONF */ [0x21] = "\x03\x19\x23\x01", 16362306a36Sopenharmony_ci /* RESET_B3_CONF */ [0x22] = "\x03\x23\x01", 16462306a36Sopenharmony_ci /* CONNECT_IND */ [0x26] = "\x03\x14\x0e\x10\x0f\x11\x0b\x28\x22\x04\x0c\x27\x2f\x1c\x01\x01", 16562306a36Sopenharmony_ci /* CONNECT_ACTIVE_IND */ [0x27] = "\x03\x16\x17\x28\x01", 16662306a36Sopenharmony_ci /* DISCONNECT_IND */ [0x28] = "\x03\x2c\x01", 16762306a36Sopenharmony_ci /* MANUFACTURER_CONF */ [0x2a] = "\x03\x2a\x15\x21\x29\x01", 16862306a36Sopenharmony_ci /* INFO_IND */ [0x2c] = "\x03\x26\x24\x01", 16962306a36Sopenharmony_ci /* FACILITY_IND */ [0x2d] = "\x03\x1f\x1d\x01", 17062306a36Sopenharmony_ci /* CONNECT_B3_IND */ [0x2f] = "\x03\x2b\x01", 17162306a36Sopenharmony_ci /* CONNECT_B3_ACTIVE_IND */ [0x30] = "\x03\x2b\x01", 17262306a36Sopenharmony_ci /* DISCONNECT_B3_IND */ [0x31] = "\x03\x2d\x2b\x01", 17362306a36Sopenharmony_ci /* DATA_B3_IND */ [0x33] = "\x03\x18\x1a\x19\x20\x01", 17462306a36Sopenharmony_ci /* RESET_B3_IND */ [0x34] = "\x03\x2b\x01", 17562306a36Sopenharmony_ci /* CONNECT_B3_T90_ACTIVE_IND */ [0x35] = "\x03\x2b\x01", 17662306a36Sopenharmony_ci /* CONNECT_RESP */ [0x38] = "\x03\x2e\x0d\x06\x08\x0a\x05\x07\x09\x01\x16\x17\x28\x04\x0c\x27\x2f\x1c\x01\x01", 17762306a36Sopenharmony_ci /* CONNECT_ACTIVE_RESP */ [0x39] = "\x03\x01", 17862306a36Sopenharmony_ci /* DISCONNECT_RESP */ [0x3a] = "\x03\x01", 17962306a36Sopenharmony_ci /* MANUFACTURER_IND */ [0x3c] = "\x03\x2a\x15\x21\x29\x01", 18062306a36Sopenharmony_ci /* INFO_RESP */ [0x3e] = "\x03\x01", 18162306a36Sopenharmony_ci /* FACILITY_RESP */ [0x3f] = "\x03\x1f\x01", 18262306a36Sopenharmony_ci /* CONNECT_B3_RESP */ [0x41] = "\x03\x2e\x2b\x01", 18362306a36Sopenharmony_ci /* CONNECT_B3_ACTIVE_RESP */ [0x42] = "\x03\x01", 18462306a36Sopenharmony_ci /* DISCONNECT_B3_RESP */ [0x43] = "\x03\x01", 18562306a36Sopenharmony_ci /* DATA_B3_RESP */ [0x45] = "\x03\x19\x01", 18662306a36Sopenharmony_ci /* RESET_B3_RESP */ [0x46] = "\x03\x01", 18762306a36Sopenharmony_ci /* CONNECT_B3_T90_ACTIVE_RESP */ [0x47] = "\x03\x01", 18862306a36Sopenharmony_ci /* MANUFACTURER_RESP */ [0x4e] = "\x03\x2a\x15\x21\x29\x01", 18962306a36Sopenharmony_ci}; 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ci/*-------------------------------------------------------*/ 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci#define byteTLcpy(x, y) *(u8 *)(x) = *(u8 *)(y); 19462306a36Sopenharmony_ci#define wordTLcpy(x, y) *(u16 *)(x) = *(u16 *)(y); 19562306a36Sopenharmony_ci#define dwordTLcpy(x, y) memcpy(x, y, 4); 19662306a36Sopenharmony_ci#define structTLcpy(x, y, l) memcpy(x, y, l) 19762306a36Sopenharmony_ci#define structTLcpyovl(x, y, l) memmove(x, y, l) 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci#define byteTRcpy(x, y) *(u8 *)(y) = *(u8 *)(x); 20062306a36Sopenharmony_ci#define wordTRcpy(x, y) *(u16 *)(y) = *(u16 *)(x); 20162306a36Sopenharmony_ci#define dwordTRcpy(x, y) memcpy(y, x, 4); 20262306a36Sopenharmony_ci#define structTRcpy(x, y, l) memcpy(y, x, l) 20362306a36Sopenharmony_ci#define structTRcpyovl(x, y, l) memmove(y, x, l) 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci/*-------------------------------------------------------*/ 20662306a36Sopenharmony_cistatic unsigned command_2_index(u8 c, u8 sc) 20762306a36Sopenharmony_ci{ 20862306a36Sopenharmony_ci if (c & 0x80) 20962306a36Sopenharmony_ci c = 0x9 + (c & 0x0f); 21062306a36Sopenharmony_ci else if (c == 0x41) 21162306a36Sopenharmony_ci c = 0x9 + 0x1; 21262306a36Sopenharmony_ci if (c > 0x18) 21362306a36Sopenharmony_ci c = 0x00; 21462306a36Sopenharmony_ci return (sc & 3) * (0x9 + 0x9) + c; 21562306a36Sopenharmony_ci} 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci/** 21862306a36Sopenharmony_ci * capi_cmd2par() - find parameter string for CAPI 2.0 command/subcommand 21962306a36Sopenharmony_ci * @cmd: command number 22062306a36Sopenharmony_ci * @subcmd: subcommand number 22162306a36Sopenharmony_ci * 22262306a36Sopenharmony_ci * Return value: static string, NULL if command/subcommand unknown 22362306a36Sopenharmony_ci */ 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cistatic unsigned char *capi_cmd2par(u8 cmd, u8 subcmd) 22662306a36Sopenharmony_ci{ 22762306a36Sopenharmony_ci return cpars[command_2_index(cmd, subcmd)]; 22862306a36Sopenharmony_ci} 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci/*-------------------------------------------------------*/ 23162306a36Sopenharmony_ci#define TYP (cdef[cmsg->par[cmsg->p]].typ) 23262306a36Sopenharmony_ci#define OFF (((u8 *)cmsg) + cdef[cmsg->par[cmsg->p]].off) 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_cistatic void jumpcstruct(_cmsg *cmsg) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci unsigned layer; 23762306a36Sopenharmony_ci for (cmsg->p++, layer = 1; layer;) { 23862306a36Sopenharmony_ci /* $$$$$ assert (cmsg->p); */ 23962306a36Sopenharmony_ci cmsg->p++; 24062306a36Sopenharmony_ci switch (TYP) { 24162306a36Sopenharmony_ci case _CMSTRUCT: 24262306a36Sopenharmony_ci layer++; 24362306a36Sopenharmony_ci break; 24462306a36Sopenharmony_ci case _CEND: 24562306a36Sopenharmony_ci layer--; 24662306a36Sopenharmony_ci break; 24762306a36Sopenharmony_ci } 24862306a36Sopenharmony_ci } 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/*-------------------------------------------------------*/ 25262306a36Sopenharmony_ci 25362306a36Sopenharmony_cistatic char *mnames[] = 25462306a36Sopenharmony_ci{ 25562306a36Sopenharmony_ci [0x01] = "ALERT_REQ", 25662306a36Sopenharmony_ci [0x02] = "CONNECT_REQ", 25762306a36Sopenharmony_ci [0x04] = "DISCONNECT_REQ", 25862306a36Sopenharmony_ci [0x05] = "LISTEN_REQ", 25962306a36Sopenharmony_ci [0x08] = "INFO_REQ", 26062306a36Sopenharmony_ci [0x09] = "FACILITY_REQ", 26162306a36Sopenharmony_ci [0x0a] = "SELECT_B_PROTOCOL_REQ", 26262306a36Sopenharmony_ci [0x0b] = "CONNECT_B3_REQ", 26362306a36Sopenharmony_ci [0x0d] = "DISCONNECT_B3_REQ", 26462306a36Sopenharmony_ci [0x0f] = "DATA_B3_REQ", 26562306a36Sopenharmony_ci [0x10] = "RESET_B3_REQ", 26662306a36Sopenharmony_ci [0x13] = "ALERT_CONF", 26762306a36Sopenharmony_ci [0x14] = "CONNECT_CONF", 26862306a36Sopenharmony_ci [0x16] = "DISCONNECT_CONF", 26962306a36Sopenharmony_ci [0x17] = "LISTEN_CONF", 27062306a36Sopenharmony_ci [0x18] = "MANUFACTURER_REQ", 27162306a36Sopenharmony_ci [0x1a] = "INFO_CONF", 27262306a36Sopenharmony_ci [0x1b] = "FACILITY_CONF", 27362306a36Sopenharmony_ci [0x1c] = "SELECT_B_PROTOCOL_CONF", 27462306a36Sopenharmony_ci [0x1d] = "CONNECT_B3_CONF", 27562306a36Sopenharmony_ci [0x1f] = "DISCONNECT_B3_CONF", 27662306a36Sopenharmony_ci [0x21] = "DATA_B3_CONF", 27762306a36Sopenharmony_ci [0x22] = "RESET_B3_CONF", 27862306a36Sopenharmony_ci [0x26] = "CONNECT_IND", 27962306a36Sopenharmony_ci [0x27] = "CONNECT_ACTIVE_IND", 28062306a36Sopenharmony_ci [0x28] = "DISCONNECT_IND", 28162306a36Sopenharmony_ci [0x2a] = "MANUFACTURER_CONF", 28262306a36Sopenharmony_ci [0x2c] = "INFO_IND", 28362306a36Sopenharmony_ci [0x2d] = "FACILITY_IND", 28462306a36Sopenharmony_ci [0x2f] = "CONNECT_B3_IND", 28562306a36Sopenharmony_ci [0x30] = "CONNECT_B3_ACTIVE_IND", 28662306a36Sopenharmony_ci [0x31] = "DISCONNECT_B3_IND", 28762306a36Sopenharmony_ci [0x33] = "DATA_B3_IND", 28862306a36Sopenharmony_ci [0x34] = "RESET_B3_IND", 28962306a36Sopenharmony_ci [0x35] = "CONNECT_B3_T90_ACTIVE_IND", 29062306a36Sopenharmony_ci [0x38] = "CONNECT_RESP", 29162306a36Sopenharmony_ci [0x39] = "CONNECT_ACTIVE_RESP", 29262306a36Sopenharmony_ci [0x3a] = "DISCONNECT_RESP", 29362306a36Sopenharmony_ci [0x3c] = "MANUFACTURER_IND", 29462306a36Sopenharmony_ci [0x3e] = "INFO_RESP", 29562306a36Sopenharmony_ci [0x3f] = "FACILITY_RESP", 29662306a36Sopenharmony_ci [0x41] = "CONNECT_B3_RESP", 29762306a36Sopenharmony_ci [0x42] = "CONNECT_B3_ACTIVE_RESP", 29862306a36Sopenharmony_ci [0x43] = "DISCONNECT_B3_RESP", 29962306a36Sopenharmony_ci [0x45] = "DATA_B3_RESP", 30062306a36Sopenharmony_ci [0x46] = "RESET_B3_RESP", 30162306a36Sopenharmony_ci [0x47] = "CONNECT_B3_T90_ACTIVE_RESP", 30262306a36Sopenharmony_ci [0x4e] = "MANUFACTURER_RESP" 30362306a36Sopenharmony_ci}; 30462306a36Sopenharmony_ci 30562306a36Sopenharmony_ci/** 30662306a36Sopenharmony_ci * capi_cmd2str() - convert CAPI 2.0 command/subcommand number to name 30762306a36Sopenharmony_ci * @cmd: command number 30862306a36Sopenharmony_ci * @subcmd: subcommand number 30962306a36Sopenharmony_ci * 31062306a36Sopenharmony_ci * Return value: static string 31162306a36Sopenharmony_ci */ 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_cichar *capi_cmd2str(u8 cmd, u8 subcmd) 31462306a36Sopenharmony_ci{ 31562306a36Sopenharmony_ci char *result; 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci result = mnames[command_2_index(cmd, subcmd)]; 31862306a36Sopenharmony_ci if (result == NULL) 31962306a36Sopenharmony_ci result = "INVALID_COMMAND"; 32062306a36Sopenharmony_ci return result; 32162306a36Sopenharmony_ci} 32262306a36Sopenharmony_ci 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci/*-------------------------------------------------------*/ 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci#ifdef CONFIG_CAPI_TRACE 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci/*-------------------------------------------------------*/ 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_cistatic char *pnames[] = 33162306a36Sopenharmony_ci{ 33262306a36Sopenharmony_ci /*00 */ NULL, 33362306a36Sopenharmony_ci /*01 */ NULL, 33462306a36Sopenharmony_ci /*02 */ NULL, 33562306a36Sopenharmony_ci /*03 */ "Controller/PLCI/NCCI", 33662306a36Sopenharmony_ci /*04 */ "AdditionalInfo", 33762306a36Sopenharmony_ci /*05 */ "B1configuration", 33862306a36Sopenharmony_ci /*06 */ "B1protocol", 33962306a36Sopenharmony_ci /*07 */ "B2configuration", 34062306a36Sopenharmony_ci /*08 */ "B2protocol", 34162306a36Sopenharmony_ci /*09 */ "B3configuration", 34262306a36Sopenharmony_ci /*0a */ "B3protocol", 34362306a36Sopenharmony_ci /*0b */ "BC", 34462306a36Sopenharmony_ci /*0c */ "BChannelinformation", 34562306a36Sopenharmony_ci /*0d */ "BProtocol", 34662306a36Sopenharmony_ci /*0e */ "CalledPartyNumber", 34762306a36Sopenharmony_ci /*0f */ "CalledPartySubaddress", 34862306a36Sopenharmony_ci /*10 */ "CallingPartyNumber", 34962306a36Sopenharmony_ci /*11 */ "CallingPartySubaddress", 35062306a36Sopenharmony_ci /*12 */ "CIPmask", 35162306a36Sopenharmony_ci /*13 */ "CIPmask2", 35262306a36Sopenharmony_ci /*14 */ "CIPValue", 35362306a36Sopenharmony_ci /*15 */ "Class", 35462306a36Sopenharmony_ci /*16 */ "ConnectedNumber", 35562306a36Sopenharmony_ci /*17 */ "ConnectedSubaddress", 35662306a36Sopenharmony_ci /*18 */ "Data32", 35762306a36Sopenharmony_ci /*19 */ "DataHandle", 35862306a36Sopenharmony_ci /*1a */ "DataLength", 35962306a36Sopenharmony_ci /*1b */ "FacilityConfirmationParameter", 36062306a36Sopenharmony_ci /*1c */ "Facilitydataarray", 36162306a36Sopenharmony_ci /*1d */ "FacilityIndicationParameter", 36262306a36Sopenharmony_ci /*1e */ "FacilityRequestParameter", 36362306a36Sopenharmony_ci /*1f */ "FacilitySelector", 36462306a36Sopenharmony_ci /*20 */ "Flags", 36562306a36Sopenharmony_ci /*21 */ "Function", 36662306a36Sopenharmony_ci /*22 */ "HLC", 36762306a36Sopenharmony_ci /*23 */ "Info", 36862306a36Sopenharmony_ci /*24 */ "InfoElement", 36962306a36Sopenharmony_ci /*25 */ "InfoMask", 37062306a36Sopenharmony_ci /*26 */ "InfoNumber", 37162306a36Sopenharmony_ci /*27 */ "Keypadfacility", 37262306a36Sopenharmony_ci /*28 */ "LLC", 37362306a36Sopenharmony_ci /*29 */ "ManuData", 37462306a36Sopenharmony_ci /*2a */ "ManuID", 37562306a36Sopenharmony_ci /*2b */ "NCPI", 37662306a36Sopenharmony_ci /*2c */ "Reason", 37762306a36Sopenharmony_ci /*2d */ "Reason_B3", 37862306a36Sopenharmony_ci /*2e */ "Reject", 37962306a36Sopenharmony_ci /*2f */ "Useruserdata" 38062306a36Sopenharmony_ci}; 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci#include <linux/stdarg.h> 38362306a36Sopenharmony_ci 38462306a36Sopenharmony_ci/*-------------------------------------------------------*/ 38562306a36Sopenharmony_cistatic _cdebbuf *bufprint(_cdebbuf *cdb, char *fmt, ...) 38662306a36Sopenharmony_ci{ 38762306a36Sopenharmony_ci va_list f; 38862306a36Sopenharmony_ci size_t n, r; 38962306a36Sopenharmony_ci 39062306a36Sopenharmony_ci if (!cdb) 39162306a36Sopenharmony_ci return NULL; 39262306a36Sopenharmony_ci va_start(f, fmt); 39362306a36Sopenharmony_ci r = cdb->size - cdb->pos; 39462306a36Sopenharmony_ci n = vsnprintf(cdb->p, r, fmt, f); 39562306a36Sopenharmony_ci va_end(f); 39662306a36Sopenharmony_ci if (n >= r) { 39762306a36Sopenharmony_ci /* truncated, need bigger buffer */ 39862306a36Sopenharmony_ci size_t ns = 2 * cdb->size; 39962306a36Sopenharmony_ci u_char *nb; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci while ((ns - cdb->pos) <= n) 40262306a36Sopenharmony_ci ns *= 2; 40362306a36Sopenharmony_ci nb = kmalloc(ns, GFP_ATOMIC); 40462306a36Sopenharmony_ci if (!nb) { 40562306a36Sopenharmony_ci cdebbuf_free(cdb); 40662306a36Sopenharmony_ci return NULL; 40762306a36Sopenharmony_ci } 40862306a36Sopenharmony_ci memcpy(nb, cdb->buf, cdb->pos); 40962306a36Sopenharmony_ci kfree(cdb->buf); 41062306a36Sopenharmony_ci nb[cdb->pos] = 0; 41162306a36Sopenharmony_ci cdb->buf = nb; 41262306a36Sopenharmony_ci cdb->p = cdb->buf + cdb->pos; 41362306a36Sopenharmony_ci cdb->size = ns; 41462306a36Sopenharmony_ci va_start(f, fmt); 41562306a36Sopenharmony_ci r = cdb->size - cdb->pos; 41662306a36Sopenharmony_ci n = vsnprintf(cdb->p, r, fmt, f); 41762306a36Sopenharmony_ci va_end(f); 41862306a36Sopenharmony_ci } 41962306a36Sopenharmony_ci cdb->p += n; 42062306a36Sopenharmony_ci cdb->pos += n; 42162306a36Sopenharmony_ci return cdb; 42262306a36Sopenharmony_ci} 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_cistatic _cdebbuf *printstructlen(_cdebbuf *cdb, u8 *m, unsigned len) 42562306a36Sopenharmony_ci{ 42662306a36Sopenharmony_ci unsigned hex = 0; 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci if (!cdb) 42962306a36Sopenharmony_ci return NULL; 43062306a36Sopenharmony_ci for (; len; len--, m++) 43162306a36Sopenharmony_ci if (isalnum(*m) || *m == ' ') { 43262306a36Sopenharmony_ci if (hex) 43362306a36Sopenharmony_ci cdb = bufprint(cdb, ">"); 43462306a36Sopenharmony_ci cdb = bufprint(cdb, "%c", *m); 43562306a36Sopenharmony_ci hex = 0; 43662306a36Sopenharmony_ci } else { 43762306a36Sopenharmony_ci if (!hex) 43862306a36Sopenharmony_ci cdb = bufprint(cdb, "<%02x", *m); 43962306a36Sopenharmony_ci else 44062306a36Sopenharmony_ci cdb = bufprint(cdb, " %02x", *m); 44162306a36Sopenharmony_ci hex = 1; 44262306a36Sopenharmony_ci } 44362306a36Sopenharmony_ci if (hex) 44462306a36Sopenharmony_ci cdb = bufprint(cdb, ">"); 44562306a36Sopenharmony_ci return cdb; 44662306a36Sopenharmony_ci} 44762306a36Sopenharmony_ci 44862306a36Sopenharmony_cistatic _cdebbuf *printstruct(_cdebbuf *cdb, u8 *m) 44962306a36Sopenharmony_ci{ 45062306a36Sopenharmony_ci unsigned len; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci if (m[0] != 0xff) { 45362306a36Sopenharmony_ci len = m[0]; 45462306a36Sopenharmony_ci m += 1; 45562306a36Sopenharmony_ci } else { 45662306a36Sopenharmony_ci len = ((u16 *) (m + 1))[0]; 45762306a36Sopenharmony_ci m += 3; 45862306a36Sopenharmony_ci } 45962306a36Sopenharmony_ci cdb = printstructlen(cdb, m, len); 46062306a36Sopenharmony_ci return cdb; 46162306a36Sopenharmony_ci} 46262306a36Sopenharmony_ci 46362306a36Sopenharmony_ci/*-------------------------------------------------------*/ 46462306a36Sopenharmony_ci#define NAME (pnames[cmsg->par[cmsg->p]]) 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_cistatic _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level) 46762306a36Sopenharmony_ci{ 46862306a36Sopenharmony_ci if (!cmsg->par) 46962306a36Sopenharmony_ci return NULL; /* invalid command/subcommand */ 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci for (; TYP != _CEND; cmsg->p++) { 47262306a36Sopenharmony_ci int slen = 29 + 3 - level; 47362306a36Sopenharmony_ci int i; 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci if (!cdb) 47662306a36Sopenharmony_ci return NULL; 47762306a36Sopenharmony_ci cdb = bufprint(cdb, " "); 47862306a36Sopenharmony_ci for (i = 0; i < level - 1; i++) 47962306a36Sopenharmony_ci cdb = bufprint(cdb, " "); 48062306a36Sopenharmony_ci 48162306a36Sopenharmony_ci switch (TYP) { 48262306a36Sopenharmony_ci case _CBYTE: 48362306a36Sopenharmony_ci cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u8 *) (cmsg->m + cmsg->l)); 48462306a36Sopenharmony_ci cmsg->l++; 48562306a36Sopenharmony_ci break; 48662306a36Sopenharmony_ci case _CWORD: 48762306a36Sopenharmony_ci cdb = bufprint(cdb, "%-*s = 0x%x\n", slen, NAME, *(u16 *) (cmsg->m + cmsg->l)); 48862306a36Sopenharmony_ci cmsg->l += 2; 48962306a36Sopenharmony_ci break; 49062306a36Sopenharmony_ci case _CDWORD: 49162306a36Sopenharmony_ci cdb = bufprint(cdb, "%-*s = 0x%lx\n", slen, NAME, *(u32 *) (cmsg->m + cmsg->l)); 49262306a36Sopenharmony_ci cmsg->l += 4; 49362306a36Sopenharmony_ci break; 49462306a36Sopenharmony_ci case _CSTRUCT: 49562306a36Sopenharmony_ci cdb = bufprint(cdb, "%-*s = ", slen, NAME); 49662306a36Sopenharmony_ci if (cmsg->m[cmsg->l] == '\0') 49762306a36Sopenharmony_ci cdb = bufprint(cdb, "default"); 49862306a36Sopenharmony_ci else 49962306a36Sopenharmony_ci cdb = printstruct(cdb, cmsg->m + cmsg->l); 50062306a36Sopenharmony_ci cdb = bufprint(cdb, "\n"); 50162306a36Sopenharmony_ci if (cmsg->m[cmsg->l] != 0xff) 50262306a36Sopenharmony_ci cmsg->l += 1 + cmsg->m[cmsg->l]; 50362306a36Sopenharmony_ci else 50462306a36Sopenharmony_ci cmsg->l += 3 + *(u16 *) (cmsg->m + cmsg->l + 1); 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci break; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci case _CMSTRUCT: 50962306a36Sopenharmony_ci/*----- Metastruktur 0 -----*/ 51062306a36Sopenharmony_ci if (cmsg->m[cmsg->l] == '\0') { 51162306a36Sopenharmony_ci cdb = bufprint(cdb, "%-*s = default\n", slen, NAME); 51262306a36Sopenharmony_ci cmsg->l++; 51362306a36Sopenharmony_ci jumpcstruct(cmsg); 51462306a36Sopenharmony_ci } else { 51562306a36Sopenharmony_ci char *name = NAME; 51662306a36Sopenharmony_ci unsigned _l = cmsg->l; 51762306a36Sopenharmony_ci cdb = bufprint(cdb, "%-*s\n", slen, name); 51862306a36Sopenharmony_ci cmsg->l = (cmsg->m + _l)[0] == 255 ? cmsg->l + 3 : cmsg->l + 1; 51962306a36Sopenharmony_ci cmsg->p++; 52062306a36Sopenharmony_ci cdb = protocol_message_2_pars(cdb, cmsg, level + 1); 52162306a36Sopenharmony_ci } 52262306a36Sopenharmony_ci break; 52362306a36Sopenharmony_ci } 52462306a36Sopenharmony_ci } 52562306a36Sopenharmony_ci return cdb; 52662306a36Sopenharmony_ci} 52762306a36Sopenharmony_ci/*-------------------------------------------------------*/ 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_cistatic _cdebbuf *g_debbuf; 53062306a36Sopenharmony_cistatic u_long g_debbuf_lock; 53162306a36Sopenharmony_cistatic _cmsg *g_cmsg; 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_cistatic _cdebbuf *cdebbuf_alloc(void) 53462306a36Sopenharmony_ci{ 53562306a36Sopenharmony_ci _cdebbuf *cdb; 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci if (likely(!test_and_set_bit(1, &g_debbuf_lock))) { 53862306a36Sopenharmony_ci cdb = g_debbuf; 53962306a36Sopenharmony_ci goto init; 54062306a36Sopenharmony_ci } else 54162306a36Sopenharmony_ci cdb = kmalloc(sizeof(_cdebbuf), GFP_ATOMIC); 54262306a36Sopenharmony_ci if (!cdb) 54362306a36Sopenharmony_ci return NULL; 54462306a36Sopenharmony_ci cdb->buf = kmalloc(CDEBUG_SIZE, GFP_ATOMIC); 54562306a36Sopenharmony_ci if (!cdb->buf) { 54662306a36Sopenharmony_ci kfree(cdb); 54762306a36Sopenharmony_ci return NULL; 54862306a36Sopenharmony_ci } 54962306a36Sopenharmony_ci cdb->size = CDEBUG_SIZE; 55062306a36Sopenharmony_ciinit: 55162306a36Sopenharmony_ci cdb->buf[0] = 0; 55262306a36Sopenharmony_ci cdb->p = cdb->buf; 55362306a36Sopenharmony_ci cdb->pos = 0; 55462306a36Sopenharmony_ci return cdb; 55562306a36Sopenharmony_ci} 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci/** 55862306a36Sopenharmony_ci * cdebbuf_free() - free CAPI debug buffer 55962306a36Sopenharmony_ci * @cdb: buffer to free 56062306a36Sopenharmony_ci */ 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_civoid cdebbuf_free(_cdebbuf *cdb) 56362306a36Sopenharmony_ci{ 56462306a36Sopenharmony_ci if (likely(cdb == g_debbuf)) { 56562306a36Sopenharmony_ci test_and_clear_bit(1, &g_debbuf_lock); 56662306a36Sopenharmony_ci return; 56762306a36Sopenharmony_ci } 56862306a36Sopenharmony_ci if (likely(cdb)) 56962306a36Sopenharmony_ci kfree(cdb->buf); 57062306a36Sopenharmony_ci kfree(cdb); 57162306a36Sopenharmony_ci} 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci 57462306a36Sopenharmony_ci/** 57562306a36Sopenharmony_ci * capi_message2str() - format CAPI 2.0 message for printing 57662306a36Sopenharmony_ci * @msg: CAPI 2.0 message 57762306a36Sopenharmony_ci * 57862306a36Sopenharmony_ci * Allocates a CAPI debug buffer and fills it with a printable representation 57962306a36Sopenharmony_ci * of the CAPI 2.0 message in @msg. 58062306a36Sopenharmony_ci * Return value: allocated debug buffer, NULL on error 58162306a36Sopenharmony_ci * The returned buffer should be freed by a call to cdebbuf_free() after use. 58262306a36Sopenharmony_ci */ 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci_cdebbuf *capi_message2str(u8 *msg) 58562306a36Sopenharmony_ci{ 58662306a36Sopenharmony_ci _cdebbuf *cdb; 58762306a36Sopenharmony_ci _cmsg *cmsg; 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci cdb = cdebbuf_alloc(); 59062306a36Sopenharmony_ci if (unlikely(!cdb)) 59162306a36Sopenharmony_ci return NULL; 59262306a36Sopenharmony_ci if (likely(cdb == g_debbuf)) 59362306a36Sopenharmony_ci cmsg = g_cmsg; 59462306a36Sopenharmony_ci else 59562306a36Sopenharmony_ci cmsg = kmalloc(sizeof(_cmsg), GFP_ATOMIC); 59662306a36Sopenharmony_ci if (unlikely(!cmsg)) { 59762306a36Sopenharmony_ci cdebbuf_free(cdb); 59862306a36Sopenharmony_ci return NULL; 59962306a36Sopenharmony_ci } 60062306a36Sopenharmony_ci cmsg->m = msg; 60162306a36Sopenharmony_ci cmsg->l = 8; 60262306a36Sopenharmony_ci cmsg->p = 0; 60362306a36Sopenharmony_ci byteTRcpy(cmsg->m + 4, &cmsg->Command); 60462306a36Sopenharmony_ci byteTRcpy(cmsg->m + 5, &cmsg->Subcommand); 60562306a36Sopenharmony_ci cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand); 60662306a36Sopenharmony_ci 60762306a36Sopenharmony_ci cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n", 60862306a36Sopenharmony_ci capi_cmd2str(cmsg->Command, cmsg->Subcommand), 60962306a36Sopenharmony_ci ((unsigned short *) msg)[1], 61062306a36Sopenharmony_ci ((unsigned short *) msg)[3], 61162306a36Sopenharmony_ci ((unsigned short *) msg)[0]); 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci cdb = protocol_message_2_pars(cdb, cmsg, 1); 61462306a36Sopenharmony_ci if (unlikely(cmsg != g_cmsg)) 61562306a36Sopenharmony_ci kfree(cmsg); 61662306a36Sopenharmony_ci return cdb; 61762306a36Sopenharmony_ci} 61862306a36Sopenharmony_ci 61962306a36Sopenharmony_ciint __init cdebug_init(void) 62062306a36Sopenharmony_ci{ 62162306a36Sopenharmony_ci g_cmsg = kmalloc(sizeof(_cmsg), GFP_KERNEL); 62262306a36Sopenharmony_ci if (!g_cmsg) 62362306a36Sopenharmony_ci return -ENOMEM; 62462306a36Sopenharmony_ci g_debbuf = kmalloc(sizeof(_cdebbuf), GFP_KERNEL); 62562306a36Sopenharmony_ci if (!g_debbuf) { 62662306a36Sopenharmony_ci kfree(g_cmsg); 62762306a36Sopenharmony_ci return -ENOMEM; 62862306a36Sopenharmony_ci } 62962306a36Sopenharmony_ci g_debbuf->buf = kmalloc(CDEBUG_GSIZE, GFP_KERNEL); 63062306a36Sopenharmony_ci if (!g_debbuf->buf) { 63162306a36Sopenharmony_ci kfree(g_cmsg); 63262306a36Sopenharmony_ci kfree(g_debbuf); 63362306a36Sopenharmony_ci return -ENOMEM; 63462306a36Sopenharmony_ci } 63562306a36Sopenharmony_ci g_debbuf->size = CDEBUG_GSIZE; 63662306a36Sopenharmony_ci g_debbuf->buf[0] = 0; 63762306a36Sopenharmony_ci g_debbuf->p = g_debbuf->buf; 63862306a36Sopenharmony_ci g_debbuf->pos = 0; 63962306a36Sopenharmony_ci return 0; 64062306a36Sopenharmony_ci} 64162306a36Sopenharmony_ci 64262306a36Sopenharmony_civoid cdebug_exit(void) 64362306a36Sopenharmony_ci{ 64462306a36Sopenharmony_ci if (g_debbuf) 64562306a36Sopenharmony_ci kfree(g_debbuf->buf); 64662306a36Sopenharmony_ci kfree(g_debbuf); 64762306a36Sopenharmony_ci kfree(g_cmsg); 64862306a36Sopenharmony_ci} 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci#else /* !CONFIG_CAPI_TRACE */ 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_cistatic _cdebbuf g_debbuf = {"CONFIG_CAPI_TRACE not enabled", NULL, 0, 0}; 65362306a36Sopenharmony_ci 65462306a36Sopenharmony_ci_cdebbuf *capi_message2str(u8 *msg) 65562306a36Sopenharmony_ci{ 65662306a36Sopenharmony_ci return &g_debbuf; 65762306a36Sopenharmony_ci} 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci_cdebbuf *capi_cmsg2str(_cmsg *cmsg) 66062306a36Sopenharmony_ci{ 66162306a36Sopenharmony_ci return &g_debbuf; 66262306a36Sopenharmony_ci} 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_civoid cdebbuf_free(_cdebbuf *cdb) 66562306a36Sopenharmony_ci{ 66662306a36Sopenharmony_ci} 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ciint __init cdebug_init(void) 66962306a36Sopenharmony_ci{ 67062306a36Sopenharmony_ci return 0; 67162306a36Sopenharmony_ci} 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_civoid cdebug_exit(void) 67462306a36Sopenharmony_ci{ 67562306a36Sopenharmony_ci} 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci#endif 678