21 #include <linux/export.h>
24 #define CapiNcpiNotSupportedByProtocol 0x0001
25 #define CapiFlagsNotSupportedByProtocol 0x0002
26 #define CapiAlertAlreadySent 0x0003
27 #define CapiFacilitySpecificFunctionNotSupported 0x3011
30 #define CAPI_CONNECT_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 2 + 8 * 1)
31 #define CAPI_CONNECT_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 3 * 1)
32 #define CAPI_CONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 1)
33 #define CAPI_CONNECT_B3_ACTIVE_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 1)
34 #define CAPI_DATA_B3_REQ_LEN64 (CAPI_MSG_BASELEN + 4 + 4 + 2 + 2 + 2 + 8)
35 #define CAPI_DATA_B3_CONF_LEN (CAPI_MSG_BASELEN + 4 + 2 + 2)
36 #define CAPI_DISCONNECT_IND_LEN (CAPI_MSG_BASELEN + 4 + 2)
37 #define CAPI_DISCONNECT_B3_IND_BASELEN (CAPI_MSG_BASELEN + 4 + 2 + 1)
38 #define CAPI_FACILITY_CONF_BASELEN (CAPI_MSG_BASELEN + 4 + 2 + 2 + 1)
40 #define CAPI_STDCONF_LEN (CAPI_MSG_BASELEN + 4 + 2)
42 #define CAPI_FACILITY_HANDSET 0x0000
43 #define CAPI_FACILITY_DTMF 0x0001
44 #define CAPI_FACILITY_V42BIS 0x0002
45 #define CAPI_FACILITY_SUPPSVC 0x0003
46 #define CAPI_FACILITY_WAKEUP 0x0004
47 #define CAPI_FACILITY_LI 0x0005
49 #define CAPI_SUPPSVC_GETSUPPORTED 0x0000
50 #define CAPI_SUPPSVC_LISTEN 0x0001
53 #define CAPIMSG_PLCI_PART(m) CAPIMSG_U8(m, 9)
54 #define CAPIMSG_NCCI_PART(m) CAPIMSG_U16(m, 10)
55 #define CAPIMSG_HANDLE_REQ(m) CAPIMSG_U16(m, 18)
56 #define CAPIMSG_FLAGS(m) CAPIMSG_U16(m, 20)
57 #define CAPIMSG_SETCONTROLLER(m, contr) capimsg_setu8(m, 8, contr)
58 #define CAPIMSG_SETPLCI_PART(m, plci) capimsg_setu8(m, 9, plci)
59 #define CAPIMSG_SETNCCI_PART(m, ncci) capimsg_setu16(m, 10, ncci)
60 #define CAPIMSG_SETFLAGS(m, flags) capimsg_setu16(m, 20, flags)
63 #define CAPIMSG_SETHANDLE_CONF(m, handle) capimsg_setu16(m, 12, handle)
64 #define CAPIMSG_SETINFO_CONF(m, info) capimsg_setu16(m, 14, info)
67 #define CAPI_FLAGS_DELIVERY_CONFIRMATION 0x04
68 #define CAPI_FLAGS_RESERVED (~0x1f)
71 #define MAX_BC_OCTETS 11
72 #define MAX_HLC_OCTETS 3
73 #define MAX_NUMBER_DIGITS 20
74 #define MAX_FMT_IE_LEN 20
78 #define APCONN_SETUP 1
79 #define APCONN_ACTIVE 2
112 [1] = {
"8090A3",
NULL },
113 [2] = {
"8890",
NULL },
114 [3] = {
"8990",
NULL },
115 [4] = {
"9090A3",
NULL },
116 [5] = {
"9190",
NULL },
117 [6] = {
"9890",
NULL },
118 [7] = {
"88C0C6E6",
NULL },
119 [8] = {
"8890218F",
NULL },
120 [9] = {
"9190A5",
NULL },
122 [16] = {
"8090A3",
"9181" },
123 [17] = {
"9090A3",
"9184" },
124 [18] = {
"8890",
"91A1" },
125 [19] = {
"8890",
"91A4" },
128 [20] = {
"8890",
"91A8" },
130 [21] = {
"8890",
"91B1" },
131 [22] = {
"8890",
"91B2" },
133 [23] = {
"8890",
"91B5" },
134 [24] = {
"8890",
"91B8" },
136 [25] = {
"8890",
"91C1" },
138 [26] = {
"9190A5",
"9181" },
139 [27] = {
"9190A5",
"916001" },
140 [28] = {
"8890",
"916002" },
152 char *msgname,
char *paramname)
155 dev_warn(cs->
dev,
"%s: ignoring unsupported parameter: %s\n",
164 static int encode_ie(
char *
in,
u8 *
out,
int maxlen)
181 static void decode_ie(
u8 *in,
char *out)
210 #ifdef CONFIG_GIGASET_DEBUG
222 gig_dbg(level,
"%s: [%d] %s", tag, p->ApplId, cdb->
buf);
225 gig_dbg(level,
"%s: [%d] %s", tag, p->ApplId,
231 static inline void dump_rawmsg(
enum debuglevel level,
const char *tag,
234 #ifdef CONFIG_GIGASET_DEBUG
243 gig_dbg(level,
"%s: ??? LEN=%04d", tag, l);
246 gig_dbg(level,
"%s: 0x%02x:0x%02x: ID=%03d #0x%04x LEN=%04d NCCI=0x%x",
254 for (i = 0; i <
l; i++) {
256 dbgline[3 * i + 1] =
hex_asc_lo(data[12 + i]);
257 dbgline[3 * i + 2] =
' ';
259 dbgline[3 * l - 1] =
'\0';
260 gig_dbg(level,
" %s", dbgline);
266 gig_dbg(level,
" DataLength=%d", l);
275 for (i = 0; i <
l; i++) {
278 dbgline[3 * i + 2] =
' ';
280 dbgline[3 * l - 1] =
'\0';
281 gig_dbg(level,
" %s", dbgline);
291 #ifdef CONFIG_GIGASET_DEBUG
292 static const char *format_ie(
const char *ie)
331 dev_err(cs->
dev,
"%s: out of memory\n", __func__);
371 unsigned char *
req = skb_mac_header(dskb);
396 (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) ?
499 unsigned int msgsize;
532 if (cip2bchlc[i].
bc != NULL &&
533 cip2bchlc[i].
hlc == NULL &&
563 if (cip2bchlc[i].
hlc != NULL &&
577 dev_warn(cs->
dev,
"RING ignored - bad number %s\n",
592 dev_warn(cs->
dev,
"RING ignored - bad number %s\n",
627 dev_warn(cs->
dev,
"%s: channel not properly cleared (%p/%d)\n",
632 spin_unlock_irqrestore(&bcs->
aplock, flags);
655 spin_unlock_irqrestore(&bcs->
aplock, flags);
673 static void send_disconnect_ind(
struct bc_state *bcs,
689 dev_err(cs->
dev,
"%s: out of memory\n", __func__);
702 static void send_disconnect_b3_ind(
struct bc_state *bcs,
716 iif->
ctr.cnr | ((bcs->
channel + 1) << 8) | (1 << 16));
719 dev_err(cs->
dev,
"%s: out of memory\n", __func__);
741 unsigned int msgsize;
747 spin_unlock_irqrestore(&bcs->
aplock, flags);
752 spin_unlock_irqrestore(&bcs->
aplock, flags);
753 dev_warn(cs->
dev,
"%s: application %u not connected\n",
757 spin_unlock_irqrestore(&bcs->
aplock, flags);
760 dev_warn(cs->
dev,
"%s: dropping extra application %u\n",
761 __func__, ap->
bcnext->id);
762 send_disconnect_ind(bcs, ap->
bcnext,
785 dev_err(cs->
dev,
"%s: out of memory\n", __func__);
811 while (bcs->
ap != NULL) {
814 spin_unlock_irqrestore(&bcs->
aplock, flags);
815 send_disconnect_b3_ind(bcs, ap);
816 send_disconnect_ind(bcs, ap, 0);
820 spin_unlock_irqrestore(&bcs->
aplock, flags);
837 unsigned int msgsize;
843 spin_unlock_irqrestore(&bcs->
aplock, flags);
848 spin_unlock_irqrestore(&bcs->
aplock, flags);
849 dev_warn(cs->
dev,
"%s: application %u not connected\n",
869 spin_unlock_irqrestore(&bcs->
aplock, flags);
873 dev_warn(cs->
dev,
"%s: dropping extra application %u\n",
874 __func__, ap->
bcnext->id);
875 send_disconnect_ind(bcs, ap->
bcnext,
882 iif->
ctr.cnr | ((bcs->
channel + 1) << 8) | (1 << 16));
885 dev_err(cs->
dev,
"%s: out of memory\n", __func__);
911 send_disconnect_b3_ind(bcs, ap);
928 iif->
ctr.version.majorversion = 2;
929 iif->
ctr.version.minorversion = 0;
931 iif->
ctr.version.majormanuversion = cs->
fwver[0];
932 iif->
ctr.version.minormanuversion = cs->
fwver[1];
936 iif->
ctr.profile.goptions = 0x11;
938 iif->
ctr.profile.support1 = 0x03;
941 iif->
ctr.profile.support2 = 0x02;
943 iif->
ctr.profile.support3 = 0x01;
970 static void gigaset_register_appl(
struct capi_ctr *ctr,
u16 appl,
982 if (ap->
id == appl) {
984 "application %u already registered\n", appl);
990 dev_err(cs->
dev,
"%s: out of memory\n", __func__);
1005 static inline void remove_appl_from_channel(
struct bc_state *bcs,
1010 unsigned long flags;
1016 spin_unlock_irqrestore(&bcs->
aplock, flags);
1023 if (bcs->
ap != NULL) {
1024 spin_unlock_irqrestore(&bcs->
aplock, flags);
1031 spin_unlock_irqrestore(&bcs->
aplock, flags);
1034 dev_notice(cs->
dev,
"%s: hanging up channel %u\n",
1038 gigaset_schedule_event(cs);
1045 if (bcap->
bcnext == ap) {
1047 spin_unlock_irqrestore(&bcs->
aplock, flags);
1051 }
while (bcap != NULL);
1052 spin_unlock_irqrestore(&bcs->
aplock, flags);
1058 static void gigaset_release_appl(
struct capi_ctr *ctr,
u16 appl)
1069 if (ap->
id == appl) {
1071 for (ch = 0; ch < cs->
channels; ch++)
1072 remove_appl_from_channel(&cs->
bcs[ch], ap);
1077 dev_info(cs->
dev,
"application %u released\n", appl);
1099 capi_cmsg_answer(&iif->
acmsg);
1120 static u8 confparam[10];
1135 capimsg_setu16(confparam, 1, 2);
1142 capimsg_setu16(confparam, 1, 1);
1148 if (pparam == NULL || pparam[0] < 2) {
1149 dev_notice(cs->
dev,
"%s: %s missing\n",
"FACILITY_REQ",
1150 "Facility Request Parameter");
1163 capimsg_setu32(confparam, 6, 0);
1166 if (pparam[0] < 7 || pparam[3] < 4) {
1167 dev_notice(cs->
dev,
"%s: %s missing\n",
1168 "FACILITY_REQ",
"Notification Mask");
1169 send_conf(iif, ap, skb,
1175 "%s: unsupported supplementary service notification mask 0x%x\n",
1179 capimsg_setu16(confparam, 4,
1191 "%s: unsupported supplementary service function 0x%04x\n",
1192 "FACILITY_REQ",
function);
1197 capimsg_setu16(confparam, 4,
1202 confparam[0] = confparam[3] + 3;
1204 capimsg_setu16(confparam, 1,
function);
1212 capimsg_setu16(confparam, 1, 0);
1221 capi_cmsg_answer(cmsg);
1224 msgsize += confparam[0];
1227 dev_err(cs->
dev,
"%s: out of memory\n", __func__);
1283 unsigned long flags;
1284 int i,
l, lbc, lhlc;
1294 dev_notice(cs->
dev,
"%s: no B channel available\n",
1301 dev_warn(cs->
dev,
"%s: channel not properly cleared (%p/%d)\n",
1306 spin_unlock_irqrestore(&bcs->
aplock, flags);
1309 dev_kfree_skb(bcs->
rx_skb);
1310 gigaset_new_rx_skb(bcs);
1320 if (pp == NULL || *pp == 0) {
1321 dev_notice(cs->
dev,
"%s: %s missing\n",
1322 "CONNECT_REQ",
"Called party number");
1333 dev_notice(cs->
dev,
"%s: %s type/plan 0x%02x unsupported\n",
1334 "CONNECT_REQ",
"Called party number", *pp);
1339 if (l >= 2 && pp[0] ==
'*' && pp[1] ==
'*') {
1352 snprintf(commands[AT_DIAL], l + 3,
"D%.*s\r", l, pp);
1356 if (pp != NULL && *pp > 0) {
1367 "%s: %s type/plan 0x%02x unsupported\n",
1368 "CONNECT_REQ",
"Calling party number", *pp);
1375 dev_notice(cs->
dev,
"%s: %s IE truncated\n",
1376 "CONNECT_REQ",
"Calling party number");
1380 switch (*pp & 0xfc) {
1388 dev_notice(cs->
dev,
"%s: invalid %s 0x%02x\n",
1390 "Presentation/Screening indicator",
1405 snprintf(commands[AT_MSN], l + 8,
"^SMSN=%*s\r", l, pp);
1412 dev_notice(cs->
dev,
"%s: unknown CIP value %d\n",
1425 if (cmsg->
BC && cmsg->
BC[0])
1426 lbc = 2 * cmsg->
BC[0];
1427 else if (cip2bchlc[cmsg->
CIPValue].bc)
1431 if (cmsg->
HLC && cmsg->
HLC[0])
1432 lhlc = 2 * cmsg->
HLC[0];
1433 else if (cip2bchlc[cmsg->
CIPValue].hlc)
1444 if (!commands[
AT_BC])
1446 strcpy(commands[AT_BC],
"^SBC=");
1447 if (cmsg->
BC && cmsg->
BC[0])
1448 decode_ie(cmsg->
BC, commands[AT_BC] + 5);
1450 strcpy(commands[AT_BC] + 5,
1453 strcpy(commands[AT_BC] + lbc + 5,
";^SHLC=");
1454 if (cmsg->
HLC && cmsg->
HLC[0])
1456 decode_ie(cmsg->
HLC,
1457 commands[AT_BC] + lbc + 12);
1459 strcpy(commands[AT_BC] + lbc + 12,
1462 strcpy(commands[AT_BC] + l - 2,
"\r");
1466 dev_notice(cs->
dev,
"%s: cannot set HLC without BC\n",
1477 "B2 Protocol X.75 SLP unsupported, using Transparent\n");
1488 "B1 Protocol %u unsupported, using Transparent\n",
1494 "B2 Protocol %u unsupported, using Transparent\n",
1498 "B3 Protocol %u unsupported, using Transparent\n",
1501 "CONNECT_REQ",
"B1 Configuration");
1503 "CONNECT_REQ",
"B2 Configuration");
1505 "CONNECT_REQ",
"B3 Configuration");
1514 "CONNECT_REQ",
"Called pty subaddr");
1516 "CONNECT_REQ",
"Calling pty subaddr");
1517 ignore_cstruct_param(cs, cmsg->
LLC,
1518 "CONNECT_REQ",
"LLC");
1521 "CONNECT_REQ",
"B Channel Information");
1523 "CONNECT_REQ",
"Keypad Facility");
1525 "CONNECT_REQ",
"User-User Data");
1527 "CONNECT_REQ",
"Facility Data Array");
1534 snprintf(commands[AT_ISO], 9,
"^SISO=%u\r",
1543 gigaset_schedule_event(cs);
1548 dev_err(cs->
dev,
"%s: out of memory\n", __func__);
1552 for (i = 0; i <
AT_NUM; i++)
1556 send_conf(iif, ap, skb, info);
1571 unsigned long flags;
1581 if (!channel || channel > cs->
channels) {
1582 dev_notice(cs->
dev,
"%s: invalid %s 0x%02x\n",
1586 bcs = cs->
bcs + channel - 1;
1592 while (bcs->
ap != NULL) {
1596 spin_unlock_irqrestore(&bcs->
aplock, flags);
1597 send_disconnect_ind(bcs, oap,
1604 spin_unlock_irqrestore(&bcs->
aplock, flags);
1607 dev_kfree_skb(bcs->
rx_skb);
1608 gigaset_new_rx_skb(bcs);
1615 "B2 Protocol X.75 SLP unsupported, using Transparent\n");
1626 "B1 Protocol %u unsupported, using Transparent\n",
1632 "B2 Protocol %u unsupported, using Transparent\n",
1636 "B3 Protocol %u unsupported, using Transparent\n",
1639 "CONNECT_RESP",
"B1 Configuration");
1641 "CONNECT_RESP",
"B2 Configuration");
1643 "CONNECT_RESP",
"B3 Configuration");
1648 "CONNECT_RESP",
"Connected Number");
1650 "CONNECT_RESP",
"Connected Subaddress");
1651 ignore_cstruct_param(cs, cmsg->
LLC,
1652 "CONNECT_RESP",
"LLC");
1655 "CONNECT_RESP",
"BChannel Information");
1657 "CONNECT_RESP",
"Keypad Facility");
1659 "CONNECT_RESP",
"User-User Data");
1661 "CONNECT_RESP",
"Facility Data Array");
1668 gigaset_schedule_event(cs);
1673 send_disconnect_ind(bcs, ap, 0);
1677 if (bcs->
ap == ap) {
1679 if (bcs->
ap == NULL) {
1684 spin_unlock_irqrestore(&bcs->
aplock, flags);
1687 for (oap = bcs->
ap; oap != NULL; oap = oap->
bcnext) {
1690 spin_unlock_irqrestore(&bcs->
aplock, flags);
1694 spin_unlock_irqrestore(&bcs->
aplock, flags);
1695 dev_err(cs->
dev,
"%s: application %u not found\n",
1702 while (bcs->
ap != NULL) {
1706 spin_unlock_irqrestore(&bcs->
aplock, flags);
1707 send_disconnect_ind(bcs, oap,
1714 spin_unlock_irqrestore(&bcs->
aplock, flags);
1718 "CONNECT_RESP", cmsg->
Reject);
1722 gigaset_schedule_event(cs);
1746 if (!channel || channel > cs->
channels) {
1747 dev_notice(cs->
dev,
"%s: invalid %s 0x%02x\n",
1748 "CONNECT_B3_REQ",
"PLCI", cmsg->
adr.
adrPLCI);
1752 bcs = &cs->
bcs[channel - 1];
1761 ignore_cstruct_param(cs, cmsg->
NCPI,
"CONNECT_B3_REQ",
"NCPI");
1762 send_conf(iif, ap, skb,
1782 unsigned int msgsize;
1791 if (!channel || channel > cs->
channels ||
1793 dev_notice(cs->
dev,
"%s: invalid %s 0x%02x\n",
1794 "CONNECT_B3_RESP",
"NCCI", cmsg->
adr.
adrNCCI);
1798 bcs = &cs->
bcs[channel - 1];
1806 EV_HUP, NULL, 0, NULL)) {
1810 gigaset_schedule_event(cs);
1825 __skb_trim(skb, msgsize);
1853 if (!channel || channel > cs->
channels) {
1854 dev_notice(cs->
dev,
"%s: invalid %s 0x%02x\n",
1855 "DISCONNECT_REQ",
"PLCI", cmsg->
adr.
adrPLCI);
1859 bcs = cs->
bcs + channel - 1;
1864 "DISCONNECT_REQ",
"B Channel Information");
1866 "DISCONNECT_REQ",
"Keypad Facility");
1868 "DISCONNECT_REQ",
"User-User Data");
1870 "DISCONNECT_REQ",
"Facility Data Array");
1889 dev_err(cs->
dev,
"%s: out of memory\n", __func__);
1898 if (b3skb == NULL) {
1899 dev_err(cs->
dev,
"%s: out of memory\n", __func__);
1916 gigaset_schedule_event(cs);
1941 if (!channel || channel > cs->
channels ||
1943 dev_notice(cs->
dev,
"%s: invalid %s 0x%02x\n",
1944 "DISCONNECT_B3_REQ",
"NCCI", cmsg->
adr.
adrNCCI);
1948 bcs = &cs->
bcs[channel - 1];
1952 send_conf(iif, ap, skb,
1962 gigaset_schedule_event(cs);
1965 ignore_cstruct_param(cs, cmsg->
NCPI,
1966 "DISCONNECT_B3_REQ",
"NCPI");
1967 send_conf(iif, ap, skb,
1993 if (channel == 0 || channel > cs->
channels || ncci != 1) {
1994 dev_notice(cs->
dev,
"%s: invalid %s 0x%02x\n",
1999 bcs = &cs->
bcs[channel - 1];
2001 dev_notice(cs->
dev,
"%s: unexpected length %d\n",
2002 "DATA_B3_REQ", msglen);
2003 if (msglen + datalen != skb->
len)
2004 dev_notice(cs->
dev,
"%s: length mismatch (%d+%d!=%d)\n",
2005 "DATA_B3_REQ", msglen, datalen, skb->
len);
2006 if (msglen + datalen > skb->
len) {
2012 dev_notice(cs->
dev,
"%s: reserved flags set (%x)\n",
2013 "DATA_B3_REQ", flags);
2025 skb_reset_mac_header(skb);
2030 if (cs->
ops->send_skb(bcs, skb) < 0) {
2040 send_data_b3_conf(cs, &iif->
ctr, ap->
id, msgid, channel, handle,
2056 send_conf(iif, ap, skb,
2102 } capi_send_handler_table[] = {
2145 for (i = 0; i <
ARRAY_SIZE(capi_send_handler_table); i++)
2146 if (capi_send_handler_table[i].cmd == cmd)
2147 return capi_send_handler_table[
i].handler;
2170 if (skb_linearize(skb) < 0) {
2171 dev_warn(cs->
dev,
"%s: skb_linearize failed\n", __func__);
2178 dev_notice(cs->
dev,
"%s: application %u not registered\n",
2187 if (printk_ratelimit())
2188 dev_notice(cs->
dev,
"%s: unsupported message %u\n",
2201 handler(iif, ap, skb);
2208 dev_err(cs->
dev,
"%s: send queue empty\n", __func__);
2214 dev_warn(cs->
dev,
"%s: application %u vanished\n",
2221 dev_err(cs->
dev,
"%s: handler %x vanished\n",
2225 handler(iif, ap, skb);
2237 static char *gigaset_procinfo(
struct capi_ctr *ctr)
2242 static int gigaset_proc_show(
struct seq_file *
m,
void *
v)
2254 seq_printf(m,
"%-16s %d.%d.%d.%d\n",
"firmware",
2279 s =
"uninitialized";
2306 for (i = 0; i < cs->
channels; i++) {
2307 seq_printf(m,
"[%d]%-13s %d\n", i,
"corrupted",
2308 cs->
bcs[i].corrupted);
2309 seq_printf(m,
"[%d]%-13s %d\n", i,
"trans_down",
2310 cs->
bcs[i].trans_down);
2311 seq_printf(m,
"[%d]%-13s %d\n", i,
"trans_up",
2312 cs->
bcs[i].trans_up);
2313 seq_printf(m,
"[%d]%-13s %d\n", i,
"chstate",
2314 cs->
bcs[i].chstate);
2315 switch (cs->
bcs[i].proto2) {
2328 seq_printf(m,
"[%d]%-13s %s\n", i,
"proto2", s);
2335 return single_open(file, gigaset_proc_show, PDE(inode)->data);
2340 .open = gigaset_proc_open,
2360 pr_err(
"%s: out of memory\n", __func__);
2366 iif->
ctr.driverdata =
cs;
2368 iif->
ctr.driver_name =
"gigaset";
2369 iif->
ctr.load_firmware =
NULL;
2371 iif->
ctr.register_appl = gigaset_register_appl;
2372 iif->
ctr.release_appl = gigaset_release_appl;
2373 iif->
ctr.send_message = gigaset_send_message;
2374 iif->
ctr.procinfo = gigaset_procinfo;
2375 iif->
ctr.proc_fops = &gigaset_proc_fops;
2376 INIT_LIST_HEAD(&iif->
appls);
2383 pr_err(
"attach_capi_ctr failed (%d)\n", rc);
2416 pr_info(
"Kernel CAPI interface\n");