1878ed226SJulian Elischer /* 2878ed226SJulian Elischer * ng_l2cap_cmds.c 3878ed226SJulian Elischer * 4878ed226SJulian Elischer * Copyright (c) Maksim Yevmenkin <m_evmenkin@yahoo.com> 5878ed226SJulian Elischer * All rights reserved. 6878ed226SJulian Elischer * 7878ed226SJulian Elischer * Redistribution and use in source and binary forms, with or without 8878ed226SJulian Elischer * modification, are permitted provided that the following conditions 9878ed226SJulian Elischer * are met: 10878ed226SJulian Elischer * 1. Redistributions of source code must retain the above copyright 11878ed226SJulian Elischer * notice, this list of conditions and the following disclaimer. 12878ed226SJulian Elischer * 2. Redistributions in binary form must reproduce the above copyright 13878ed226SJulian Elischer * notice, this list of conditions and the following disclaimer in the 14878ed226SJulian Elischer * documentation and/or other materials provided with the distribution. 15878ed226SJulian Elischer * 16878ed226SJulian Elischer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17878ed226SJulian Elischer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18878ed226SJulian Elischer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19878ed226SJulian Elischer * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20878ed226SJulian Elischer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21878ed226SJulian Elischer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22878ed226SJulian Elischer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23878ed226SJulian Elischer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24878ed226SJulian Elischer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25878ed226SJulian Elischer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26878ed226SJulian Elischer * SUCH DAMAGE. 27878ed226SJulian Elischer * 28878ed226SJulian Elischer * $Id: ng_l2cap_cmds.c,v 1.14 2002/09/04 21:38:38 max Exp $ 29878ed226SJulian Elischer * $FreeBSD$ 30878ed226SJulian Elischer */ 31878ed226SJulian Elischer 32878ed226SJulian Elischer #include <sys/param.h> 33878ed226SJulian Elischer #include <sys/systm.h> 34878ed226SJulian Elischer #include <sys/kernel.h> 35878ed226SJulian Elischer #include <sys/endian.h> 36878ed226SJulian Elischer #include <sys/malloc.h> 37878ed226SJulian Elischer #include <sys/mbuf.h> 38878ed226SJulian Elischer #include <sys/queue.h> 39878ed226SJulian Elischer #include <netgraph/ng_message.h> 40878ed226SJulian Elischer #include <netgraph/netgraph.h> 41878ed226SJulian Elischer #include "ng_bluetooth.h" 42878ed226SJulian Elischer #include "ng_hci.h" 43878ed226SJulian Elischer #include "ng_l2cap.h" 44878ed226SJulian Elischer #include "ng_l2cap_var.h" 45878ed226SJulian Elischer #include "ng_l2cap_cmds.h" 46878ed226SJulian Elischer #include "ng_l2cap_evnt.h" 47878ed226SJulian Elischer #include "ng_l2cap_llpi.h" 48878ed226SJulian Elischer #include "ng_l2cap_ulpi.h" 49878ed226SJulian Elischer #include "ng_l2cap_misc.h" 50878ed226SJulian Elischer 51878ed226SJulian Elischer /****************************************************************************** 52878ed226SJulian Elischer ****************************************************************************** 53878ed226SJulian Elischer ** L2CAP commands processing module 54878ed226SJulian Elischer ****************************************************************************** 55878ed226SJulian Elischer ******************************************************************************/ 56878ed226SJulian Elischer 57878ed226SJulian Elischer /* 58878ed226SJulian Elischer * Process L2CAP command queue on connection 59878ed226SJulian Elischer */ 60878ed226SJulian Elischer 61878ed226SJulian Elischer void 62878ed226SJulian Elischer ng_l2cap_con_wakeup(ng_l2cap_con_p con) 63878ed226SJulian Elischer { 64878ed226SJulian Elischer ng_l2cap_cmd_p cmd = NULL; 65878ed226SJulian Elischer struct mbuf *m = NULL; 66878ed226SJulian Elischer int error = 0; 67878ed226SJulian Elischer 68878ed226SJulian Elischer /* Find first non-pending command in the queue */ 69878ed226SJulian Elischer TAILQ_FOREACH(cmd, &con->cmd_list, next) { 70878ed226SJulian Elischer KASSERT((cmd->con == con), 71878ed226SJulian Elischer ("%s: %s - invalid connection pointer!\n", 72878ed226SJulian Elischer __func__, NG_NODE_NAME(con->l2cap->node))); 73878ed226SJulian Elischer 74878ed226SJulian Elischer if (!(cmd->flags & NG_L2CAP_CMD_PENDING)) 75878ed226SJulian Elischer break; 76878ed226SJulian Elischer } 77878ed226SJulian Elischer 78878ed226SJulian Elischer if (cmd == NULL) 79878ed226SJulian Elischer return; 80878ed226SJulian Elischer 81878ed226SJulian Elischer /* Detach command packet */ 82878ed226SJulian Elischer m = cmd->aux; 83878ed226SJulian Elischer cmd->aux = NULL; 84878ed226SJulian Elischer 85878ed226SJulian Elischer /* Process command */ 86878ed226SJulian Elischer switch (cmd->code) { 87878ed226SJulian Elischer case NG_L2CAP_CMD_REJ: 88878ed226SJulian Elischer case NG_L2CAP_DISCON_RSP: 89878ed226SJulian Elischer case NG_L2CAP_ECHO_RSP: 90878ed226SJulian Elischer case NG_L2CAP_INFO_RSP: 91878ed226SJulian Elischer ng_l2cap_lp_send(con, NG_L2CAP_SIGNAL_CID, m); 92878ed226SJulian Elischer ng_l2cap_unlink_cmd(cmd); 93878ed226SJulian Elischer ng_l2cap_free_cmd(cmd); 94878ed226SJulian Elischer break; 95878ed226SJulian Elischer 96878ed226SJulian Elischer case NG_L2CAP_CON_REQ: 97878ed226SJulian Elischer error = ng_l2cap_lp_send(con, NG_L2CAP_SIGNAL_CID, m); 98878ed226SJulian Elischer if (error != 0) { 99878ed226SJulian Elischer ng_l2cap_l2ca_con_rsp(cmd->ch, cmd->token, 100878ed226SJulian Elischer NG_L2CAP_NO_RESOURCES, 0); 101878ed226SJulian Elischer ng_l2cap_free_chan(cmd->ch); /* will free commands */ 102878ed226SJulian Elischer } else 103878ed226SJulian Elischer ng_l2cap_command_timeout(cmd, 104878ed226SJulian Elischer bluetooth_l2cap_rtx_timeout()); 105878ed226SJulian Elischer break; 106878ed226SJulian Elischer 107878ed226SJulian Elischer case NG_L2CAP_CON_RSP: 108878ed226SJulian Elischer error = ng_l2cap_lp_send(con, NG_L2CAP_SIGNAL_CID, m); 109878ed226SJulian Elischer ng_l2cap_unlink_cmd(cmd); 110878ed226SJulian Elischer if (cmd->ch != NULL) { 111878ed226SJulian Elischer ng_l2cap_l2ca_con_rsp_rsp(cmd->ch, cmd->token, 112878ed226SJulian Elischer (error == 0)? NG_L2CAP_SUCCESS : 113878ed226SJulian Elischer NG_L2CAP_NO_RESOURCES); 114878ed226SJulian Elischer if (error != 0) 115878ed226SJulian Elischer ng_l2cap_free_chan(cmd->ch); 116878ed226SJulian Elischer } 117878ed226SJulian Elischer ng_l2cap_free_cmd(cmd); 118878ed226SJulian Elischer break; 119878ed226SJulian Elischer 120878ed226SJulian Elischer case NG_L2CAP_CFG_REQ: 121878ed226SJulian Elischer error = ng_l2cap_lp_send(con, NG_L2CAP_SIGNAL_CID, m); 122878ed226SJulian Elischer if (error != 0) { 123878ed226SJulian Elischer ng_l2cap_l2ca_cfg_rsp(cmd->ch, cmd->token, 124878ed226SJulian Elischer NG_L2CAP_NO_RESOURCES); 125878ed226SJulian Elischer ng_l2cap_unlink_cmd(cmd); 126878ed226SJulian Elischer ng_l2cap_free_cmd(cmd); 127878ed226SJulian Elischer } else 128878ed226SJulian Elischer ng_l2cap_command_timeout(cmd, 129878ed226SJulian Elischer bluetooth_l2cap_rtx_timeout()); 130878ed226SJulian Elischer break; 131878ed226SJulian Elischer 132878ed226SJulian Elischer case NG_L2CAP_CFG_RSP: 133878ed226SJulian Elischer error = ng_l2cap_lp_send(con, NG_L2CAP_SIGNAL_CID, m); 134878ed226SJulian Elischer ng_l2cap_unlink_cmd(cmd); 135878ed226SJulian Elischer if (cmd->ch != NULL) 136878ed226SJulian Elischer ng_l2cap_l2ca_cfg_rsp_rsp(cmd->ch, cmd->token, 137878ed226SJulian Elischer (error == 0)? NG_L2CAP_SUCCESS : 138878ed226SJulian Elischer NG_L2CAP_NO_RESOURCES); 139878ed226SJulian Elischer ng_l2cap_free_cmd(cmd); 140878ed226SJulian Elischer break; 141878ed226SJulian Elischer 142878ed226SJulian Elischer case NG_L2CAP_DISCON_REQ: 143878ed226SJulian Elischer error = ng_l2cap_lp_send(con, NG_L2CAP_SIGNAL_CID, m); 144878ed226SJulian Elischer ng_l2cap_l2ca_discon_rsp(cmd->ch, cmd->token, 145878ed226SJulian Elischer (error == 0)? NG_L2CAP_SUCCESS : NG_L2CAP_NO_RESOURCES); 146878ed226SJulian Elischer if (error != 0) 147878ed226SJulian Elischer ng_l2cap_free_chan(cmd->ch); /* XXX free channel */ 148878ed226SJulian Elischer else 149878ed226SJulian Elischer ng_l2cap_command_timeout(cmd, 150878ed226SJulian Elischer bluetooth_l2cap_rtx_timeout()); 151878ed226SJulian Elischer break; 152878ed226SJulian Elischer 153878ed226SJulian Elischer case NG_L2CAP_ECHO_REQ: 154878ed226SJulian Elischer error = ng_l2cap_lp_send(con, NG_L2CAP_SIGNAL_CID, m); 155878ed226SJulian Elischer if (error != 0) { 156878ed226SJulian Elischer ng_l2cap_l2ca_ping_rsp(con, cmd->token, 157878ed226SJulian Elischer NG_L2CAP_NO_RESOURCES, NULL); 158878ed226SJulian Elischer ng_l2cap_unlink_cmd(cmd); 159878ed226SJulian Elischer ng_l2cap_free_cmd(cmd); 160878ed226SJulian Elischer } else 161878ed226SJulian Elischer ng_l2cap_command_timeout(cmd, 162878ed226SJulian Elischer bluetooth_l2cap_rtx_timeout()); 163878ed226SJulian Elischer break; 164878ed226SJulian Elischer 165878ed226SJulian Elischer case NG_L2CAP_INFO_REQ: 166878ed226SJulian Elischer error = ng_l2cap_lp_send(con, NG_L2CAP_SIGNAL_CID, m); 167878ed226SJulian Elischer if (error != 0) { 168878ed226SJulian Elischer ng_l2cap_l2ca_get_info_rsp(con, cmd->token, 169878ed226SJulian Elischer NG_L2CAP_NO_RESOURCES, NULL); 170878ed226SJulian Elischer ng_l2cap_unlink_cmd(cmd); 171878ed226SJulian Elischer ng_l2cap_free_cmd(cmd); 172878ed226SJulian Elischer } else 173878ed226SJulian Elischer ng_l2cap_command_timeout(cmd, 174878ed226SJulian Elischer bluetooth_l2cap_rtx_timeout()); 175878ed226SJulian Elischer break; 176878ed226SJulian Elischer 177878ed226SJulian Elischer case NGM_L2CAP_L2CA_WRITE: { 178878ed226SJulian Elischer int length = m->m_pkthdr.len; 179878ed226SJulian Elischer 180878ed226SJulian Elischer if (cmd->ch->dcid == NG_L2CAP_CLT_CID) { 181878ed226SJulian Elischer m = ng_l2cap_prepend(m, sizeof(ng_l2cap_clt_hdr_t)); 182878ed226SJulian Elischer if (m == NULL) 183878ed226SJulian Elischer error = ENOBUFS; 184878ed226SJulian Elischer else 185878ed226SJulian Elischer mtod(m, ng_l2cap_clt_hdr_t *)->psm = 186878ed226SJulian Elischer htole16(cmd->ch->psm); 187878ed226SJulian Elischer } 188878ed226SJulian Elischer 189878ed226SJulian Elischer if (error == 0) 190878ed226SJulian Elischer error = ng_l2cap_lp_send(con, cmd->ch->dcid, m); 191878ed226SJulian Elischer 192878ed226SJulian Elischer ng_l2cap_l2ca_write_rsp(cmd->ch, cmd->token, 193878ed226SJulian Elischer (error == 0)? NG_L2CAP_SUCCESS : NG_L2CAP_NO_RESOURCES, 194878ed226SJulian Elischer length); 195878ed226SJulian Elischer 196878ed226SJulian Elischer ng_l2cap_unlink_cmd(cmd); 197878ed226SJulian Elischer ng_l2cap_free_cmd(cmd); 198878ed226SJulian Elischer } break; 199878ed226SJulian Elischer 200878ed226SJulian Elischer /* XXX FIXME add other commands */ 201878ed226SJulian Elischer 202878ed226SJulian Elischer default: 203878ed226SJulian Elischer KASSERT(0, 204878ed226SJulian Elischer ("%s: %s - unknown command code=%d\n", 205878ed226SJulian Elischer __func__, NG_NODE_NAME(con->l2cap->node), cmd->code)); 206878ed226SJulian Elischer 207878ed226SJulian Elischer ng_l2cap_unlink_cmd(cmd); 208878ed226SJulian Elischer ng_l2cap_free_cmd(cmd); 209878ed226SJulian Elischer break; 210878ed226SJulian Elischer } 211878ed226SJulian Elischer } /* ng_l2cap_con_wakeup */ 212878ed226SJulian Elischer 213878ed226SJulian Elischer /* 214878ed226SJulian Elischer * We have failed to open ACL connection to the remote unit. Could be negative 215878ed226SJulian Elischer * confirmation or timeout. So fail any "delayed" commands, notify upper layer, 216878ed226SJulian Elischer * remove all channels and remove connection descriptor. 217878ed226SJulian Elischer */ 218878ed226SJulian Elischer 219878ed226SJulian Elischer void 220878ed226SJulian Elischer ng_l2cap_con_fail(ng_l2cap_con_p con, u_int16_t result) 221878ed226SJulian Elischer { 222878ed226SJulian Elischer ng_l2cap_p l2cap = con->l2cap; 223878ed226SJulian Elischer ng_l2cap_cmd_p cmd = NULL; 224878ed226SJulian Elischer ng_l2cap_chan_p ch = NULL; 225878ed226SJulian Elischer 226878ed226SJulian Elischer NG_L2CAP_INFO( 227878ed226SJulian Elischer "%s: %s - ACL connection failed, result=%d\n", 228878ed226SJulian Elischer __func__, NG_NODE_NAME(l2cap->node), result); 229878ed226SJulian Elischer 230878ed226SJulian Elischer /* Clean command queue */ 231878ed226SJulian Elischer while (!TAILQ_EMPTY(&con->cmd_list)) { 232878ed226SJulian Elischer cmd = TAILQ_FIRST(&con->cmd_list); 233878ed226SJulian Elischer 234878ed226SJulian Elischer ng_l2cap_unlink_cmd(cmd); 235878ed226SJulian Elischer if(cmd->flags & NG_L2CAP_CMD_PENDING) 236878ed226SJulian Elischer ng_l2cap_command_untimeout(cmd); 237878ed226SJulian Elischer 238878ed226SJulian Elischer KASSERT((cmd->con == con), 239878ed226SJulian Elischer ("%s: %s - invalid connection pointer!\n", 240878ed226SJulian Elischer __func__, NG_NODE_NAME(con->l2cap->node))); 241878ed226SJulian Elischer 242878ed226SJulian Elischer switch (cmd->code) { 243878ed226SJulian Elischer case NG_L2CAP_CMD_REJ: 244878ed226SJulian Elischer case NG_L2CAP_DISCON_RSP: 245878ed226SJulian Elischer case NG_L2CAP_ECHO_RSP: 246878ed226SJulian Elischer case NG_L2CAP_INFO_RSP: 247878ed226SJulian Elischer break; 248878ed226SJulian Elischer 249878ed226SJulian Elischer case NG_L2CAP_CON_REQ: 250878ed226SJulian Elischer ng_l2cap_l2ca_con_rsp(cmd->ch, cmd->token, result, 0); 251878ed226SJulian Elischer break; 252878ed226SJulian Elischer 253878ed226SJulian Elischer case NG_L2CAP_CON_RSP: 254878ed226SJulian Elischer if (cmd->ch != NULL) 255878ed226SJulian Elischer ng_l2cap_l2ca_con_rsp_rsp(cmd->ch, cmd->token, 256878ed226SJulian Elischer result); 257878ed226SJulian Elischer break; 258878ed226SJulian Elischer 259878ed226SJulian Elischer case NG_L2CAP_CFG_REQ: 260878ed226SJulian Elischer case NG_L2CAP_CFG_RSP: 261878ed226SJulian Elischer case NGM_L2CAP_L2CA_WRITE: 262878ed226SJulian Elischer ng_l2cap_l2ca_discon_ind(cmd->ch); 263878ed226SJulian Elischer break; 264878ed226SJulian Elischer 265878ed226SJulian Elischer case NG_L2CAP_DISCON_REQ: 266878ed226SJulian Elischer ng_l2cap_l2ca_discon_rsp(cmd->ch, cmd->token, 267878ed226SJulian Elischer NG_L2CAP_SUCCESS); 268878ed226SJulian Elischer break; 269878ed226SJulian Elischer 270878ed226SJulian Elischer case NG_L2CAP_ECHO_REQ: 271878ed226SJulian Elischer ng_l2cap_l2ca_ping_rsp(cmd->con, cmd->token, 272878ed226SJulian Elischer result, NULL); 273878ed226SJulian Elischer break; 274878ed226SJulian Elischer 275878ed226SJulian Elischer case NG_L2CAP_INFO_REQ: 276878ed226SJulian Elischer ng_l2cap_l2ca_get_info_rsp(cmd->con, cmd->token, 277878ed226SJulian Elischer result, NULL); 278878ed226SJulian Elischer break; 279878ed226SJulian Elischer 280878ed226SJulian Elischer /* XXX FIXME add other commands */ 281878ed226SJulian Elischer 282878ed226SJulian Elischer default: 283878ed226SJulian Elischer KASSERT(0, 284878ed226SJulian Elischer ("%s: %s - unexpected command code=%d\n", 285878ed226SJulian Elischer __func__, NG_NODE_NAME(con->l2cap->node), 286878ed226SJulian Elischer cmd->code)); 287878ed226SJulian Elischer break; 288878ed226SJulian Elischer } 289878ed226SJulian Elischer 290878ed226SJulian Elischer if (cmd->ch != NULL) 291878ed226SJulian Elischer ng_l2cap_free_chan(cmd->ch); 292878ed226SJulian Elischer 293878ed226SJulian Elischer ng_l2cap_free_cmd(cmd); 294878ed226SJulian Elischer } 295878ed226SJulian Elischer 296878ed226SJulian Elischer /* 297878ed226SJulian Elischer * There still might be channels (in OPEN state?) that 298878ed226SJulian Elischer * did not submit any commands, so diconnect them 299878ed226SJulian Elischer */ 300878ed226SJulian Elischer 301878ed226SJulian Elischer LIST_FOREACH(ch, &l2cap->chan_list, next) 302878ed226SJulian Elischer if (ch->con == con) 303878ed226SJulian Elischer ng_l2cap_l2ca_discon_ind(ch); 304878ed226SJulian Elischer 305878ed226SJulian Elischer /* Free connection descriptor */ 306878ed226SJulian Elischer ng_l2cap_free_con(con); 307878ed226SJulian Elischer } /* ng_l2cap_con_fail */ 308878ed226SJulian Elischer 309878ed226SJulian Elischer /* 310878ed226SJulian Elischer * Process L2CAP command timeout. In general - notify upper layer and destroy 311878ed226SJulian Elischer * channel. Do not pay much attension to return code, just do our best. 312878ed226SJulian Elischer */ 313878ed226SJulian Elischer 314878ed226SJulian Elischer void 315878ed226SJulian Elischer ng_l2cap_process_command_timeout(node_p node, hook_p hook, void *arg1, int arg2) 316878ed226SJulian Elischer { 317878ed226SJulian Elischer ng_l2cap_cmd_p cmd = (ng_l2cap_cmd_p) arg1; 318878ed226SJulian Elischer 319878ed226SJulian Elischer KASSERT((cmd->flags & NG_L2CAP_CMD_PENDING), 320878ed226SJulian Elischer ("%s: %s - invalid command flags flags=%#x!\n", 321878ed226SJulian Elischer __func__, NG_NODE_NAME(cmd->con->l2cap->node), cmd->flags)); 322878ed226SJulian Elischer 323878ed226SJulian Elischer cmd->flags &= ~NG_L2CAP_CMD_PENDING; 324878ed226SJulian Elischer ng_l2cap_unlink_cmd(cmd); 325878ed226SJulian Elischer 326878ed226SJulian Elischer switch (cmd->code) { 327878ed226SJulian Elischer case NG_L2CAP_CON_REQ: 328878ed226SJulian Elischer ng_l2cap_l2ca_con_rsp(cmd->ch, cmd->token, NG_L2CAP_TIMEOUT, 0); 329878ed226SJulian Elischer ng_l2cap_free_chan(cmd->ch); 330878ed226SJulian Elischer break; 331878ed226SJulian Elischer 332878ed226SJulian Elischer case NG_L2CAP_CFG_REQ: 333878ed226SJulian Elischer ng_l2cap_l2ca_cfg_rsp(cmd->ch, cmd->token, NG_L2CAP_TIMEOUT); 334878ed226SJulian Elischer break; 335878ed226SJulian Elischer 336878ed226SJulian Elischer case NG_L2CAP_DISCON_REQ: 337878ed226SJulian Elischer ng_l2cap_l2ca_discon_rsp(cmd->ch, cmd->token, NG_L2CAP_TIMEOUT); 338878ed226SJulian Elischer ng_l2cap_free_chan(cmd->ch); /* XXX free channel */ 339878ed226SJulian Elischer break; 340878ed226SJulian Elischer 341878ed226SJulian Elischer case NG_L2CAP_ECHO_REQ: 342878ed226SJulian Elischer /* Echo request timed out. Let the upper layer know */ 343878ed226SJulian Elischer ng_l2cap_l2ca_ping_rsp(cmd->con, cmd->token, 344878ed226SJulian Elischer NG_L2CAP_TIMEOUT, NULL); 345878ed226SJulian Elischer break; 346878ed226SJulian Elischer 347878ed226SJulian Elischer case NG_L2CAP_INFO_REQ: 348878ed226SJulian Elischer /* Info request timed out. Let the upper layer know */ 349878ed226SJulian Elischer ng_l2cap_l2ca_get_info_rsp(cmd->con, cmd->token, 350878ed226SJulian Elischer NG_L2CAP_TIMEOUT, NULL); 351878ed226SJulian Elischer break; 352878ed226SJulian Elischer 353878ed226SJulian Elischer /* XXX FIXME add other commands */ 354878ed226SJulian Elischer 355878ed226SJulian Elischer default: 356878ed226SJulian Elischer KASSERT(0, 357878ed226SJulian Elischer ("%s: %s - unexpected command code=%d\n", 358878ed226SJulian Elischer __func__, NG_NODE_NAME(cmd->con->l2cap->node), 359878ed226SJulian Elischer cmd->code)); 360878ed226SJulian Elischer break; 361878ed226SJulian Elischer } 362878ed226SJulian Elischer 363878ed226SJulian Elischer ng_l2cap_free_cmd(cmd); 364878ed226SJulian Elischer } /* ng_l2cap_process_command_timeout */ 365878ed226SJulian Elischer 366