| 63 | */ |
| 64 | |
| 65 | void |
| 66 | ng_l2cap_con_wakeup(ng_l2cap_con_p con) |
| 67 | { |
| 68 | ng_l2cap_cmd_p cmd = NULL; |
| 69 | struct mbuf *m = NULL; |
| 70 | int error = 0; |
| 71 | |
| 72 | /* Find first non-pending command in the queue */ |
| 73 | TAILQ_FOREACH(cmd, &con->cmd_list, next) { |
| 74 | KASSERT((cmd->con == con), |
| 75 | ("%s: %s - invalid connection pointer!\n", |
| 76 | __func__, NG_NODE_NAME(con->l2cap->node))); |
| 77 | |
| 78 | if (!(cmd->flags & NG_L2CAP_CMD_PENDING)) |
| 79 | break; |
| 80 | } |
| 81 | |
| 82 | if (cmd == NULL) |
| 83 | return; |
| 84 | |
| 85 | /* Detach command packet */ |
| 86 | m = cmd->aux; |
| 87 | cmd->aux = NULL; |
| 88 | |
| 89 | /* Process command */ |
| 90 | switch (cmd->code) { |
| 91 | case NG_L2CAP_DISCON_RSP: |
| 92 | case NG_L2CAP_ECHO_RSP: |
| 93 | case NG_L2CAP_INFO_RSP: |
| 94 | /* |
| 95 | * Do not check return ng_l2cap_lp_send() value, because |
| 96 | * in these cases we do not really have a graceful way out. |
| 97 | * ECHO and INFO responses are internal to the stack and not |
| 98 | * visible to user. REJect is just being nice to remote end |
| 99 | * (otherwise remote end will timeout anyway). DISCON is |
| 100 | * probably most interesting here, however, if it fails |
| 101 | * there is nothing we can do anyway. |
| 102 | */ |
| 103 | |
| 104 | (void) ng_l2cap_lp_send(con, NG_L2CAP_SIGNAL_CID, m); |
| 105 | ng_l2cap_unlink_cmd(cmd); |
| 106 | ng_l2cap_free_cmd(cmd); |
| 107 | break; |
| 108 | case NG_L2CAP_CMD_REJ: |
| 109 | (void) ng_l2cap_lp_send(con, |
| 110 | (con->linktype == NG_HCI_LINK_ACL)? |
| 111 | NG_L2CAP_SIGNAL_CID: |
| 112 | NG_L2CAP_LESIGNAL_CID |
| 113 | , m); |
| 114 | ng_l2cap_unlink_cmd(cmd); |
| 115 | ng_l2cap_free_cmd(cmd); |
| 116 | break; |
| 117 | |
| 118 | case NG_L2CAP_CON_REQ: |
| 119 | error = ng_l2cap_lp_send(con, NG_L2CAP_SIGNAL_CID, m); |
| 120 | if (error != 0) { |
| 121 | ng_l2cap_l2ca_con_rsp(cmd->ch, cmd->token, |
| 122 | NG_L2CAP_NO_RESOURCES, 0); |
no test coverage detected