@@ -5969,16 +5969,12 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
59695969 hci_dev_unlock (hdev );
59705970}
59715971
5972- static void hci_le_conn_complete_evt (struct hci_dev * hdev , struct sk_buff * skb )
5972+ static void hci_le_conn_complete_evt (struct hci_dev * hdev , void * data ,
5973+ struct sk_buff * skb )
59735974{
5974- struct hci_ev_le_conn_complete * ev ;
5975-
5976- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_CONN_COMPLETE ,
5977- sizeof (* ev ));
5978- if (!ev )
5979- return ;
5975+ struct hci_ev_le_conn_complete * ev = data ;
59805976
5981- BT_DBG ( "%s status 0x%2.2x", hdev -> name , ev -> status );
5977+ bt_dev_dbg ( hdev , " status 0x%2.2x" , ev -> status );
59825978
59835979 le_conn_complete_evt (hdev , ev -> status , & ev -> bdaddr , ev -> bdaddr_type ,
59845980 NULL , ev -> role , le16_to_cpu (ev -> handle ),
@@ -5987,17 +5983,12 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
59875983 le16_to_cpu (ev -> supervision_timeout ));
59885984}
59895985
5990- static void hci_le_enh_conn_complete_evt (struct hci_dev * hdev ,
5986+ static void hci_le_enh_conn_complete_evt (struct hci_dev * hdev , void * data ,
59915987 struct sk_buff * skb )
59925988{
5993- struct hci_ev_le_enh_conn_complete * ev ;
5989+ struct hci_ev_le_enh_conn_complete * ev = data ;
59945990
5995- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_ENHANCED_CONN_COMPLETE ,
5996- sizeof (* ev ));
5997- if (!ev )
5998- return ;
5999-
6000- BT_DBG ("%s status 0x%2.2x" , hdev -> name , ev -> status );
5991+ bt_dev_dbg (hdev , "status 0x%2.2x" , ev -> status );
60015992
60025993 le_conn_complete_evt (hdev , ev -> status , & ev -> bdaddr , ev -> bdaddr_type ,
60035994 & ev -> local_rpa , ev -> role , le16_to_cpu (ev -> handle ),
@@ -6006,18 +5997,14 @@ static void hci_le_enh_conn_complete_evt(struct hci_dev *hdev,
60065997 le16_to_cpu (ev -> supervision_timeout ));
60075998}
60085999
6009- static void hci_le_ext_adv_term_evt (struct hci_dev * hdev , struct sk_buff * skb )
6000+ static void hci_le_ext_adv_term_evt (struct hci_dev * hdev , void * data ,
6001+ struct sk_buff * skb )
60106002{
6011- struct hci_evt_le_ext_adv_set_term * ev ;
6003+ struct hci_evt_le_ext_adv_set_term * ev = data ;
60126004 struct hci_conn * conn ;
60136005 struct adv_info * adv , * n ;
60146006
6015- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_EXT_ADV_SET_TERM ,
6016- sizeof (* ev ));
6017- if (!ev )
6018- return ;
6019-
6020- BT_DBG ("%s status 0x%2.2x" , hdev -> name , ev -> status );
6007+ bt_dev_dbg (hdev , "status 0x%2.2x" , ev -> status );
60216008
60226009 adv = hci_find_adv_instance (hdev , ev -> handle );
60236010
@@ -6075,18 +6062,13 @@ static void hci_le_ext_adv_term_evt(struct hci_dev *hdev, struct sk_buff *skb)
60756062 }
60766063}
60776064
6078- static void hci_le_conn_update_complete_evt (struct hci_dev * hdev ,
6065+ static void hci_le_conn_update_complete_evt (struct hci_dev * hdev , void * data ,
60796066 struct sk_buff * skb )
60806067{
6081- struct hci_ev_le_conn_update_complete * ev ;
6068+ struct hci_ev_le_conn_update_complete * ev = data ;
60826069 struct hci_conn * conn ;
60836070
6084- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_CONN_UPDATE_COMPLETE ,
6085- sizeof (* ev ));
6086- if (!ev )
6087- return ;
6088-
6089- BT_DBG ("%s status 0x%2.2x" , hdev -> name , ev -> status );
6071+ bt_dev_dbg (hdev , "status 0x%2.2x" , ev -> status );
60906072
60916073 if (ev -> status )
60926074 return ;
@@ -6402,14 +6384,10 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
64026384 clear_pending_adv_report (hdev );
64036385}
64046386
6405- static void hci_le_adv_report_evt (struct hci_dev * hdev , struct sk_buff * skb )
6387+ static void hci_le_adv_report_evt (struct hci_dev * hdev , void * data ,
6388+ struct sk_buff * skb )
64066389{
6407- struct hci_ev_le_advertising_report * ev ;
6408-
6409- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_ADVERTISING_REPORT ,
6410- sizeof (* ev ));
6411- if (!ev )
6412- return ;
6390+ struct hci_ev_le_advertising_report * ev = data ;
64136391
64146392 if (!ev -> num )
64156393 return ;
@@ -6487,14 +6465,10 @@ static u8 ext_evt_type_to_legacy(struct hci_dev *hdev, u16 evt_type)
64876465 return LE_ADV_INVALID ;
64886466}
64896467
6490- static void hci_le_ext_adv_report_evt (struct hci_dev * hdev , struct sk_buff * skb )
6468+ static void hci_le_ext_adv_report_evt (struct hci_dev * hdev , void * data ,
6469+ struct sk_buff * skb )
64916470{
6492- struct hci_ev_le_ext_adv_report * ev ;
6493-
6494- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_EXT_ADV_REPORT ,
6495- sizeof (* ev ));
6496- if (!ev )
6497- return ;
6471+ struct hci_ev_le_ext_adv_report * ev = data ;
64986472
64996473 if (!ev -> num )
65006474 return ;
@@ -6528,18 +6502,13 @@ static void hci_le_ext_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
65286502 hci_dev_unlock (hdev );
65296503}
65306504
6531- static void hci_le_remote_feat_complete_evt (struct hci_dev * hdev ,
6505+ static void hci_le_remote_feat_complete_evt (struct hci_dev * hdev , void * data ,
65326506 struct sk_buff * skb )
65336507{
6534- struct hci_ev_le_remote_feat_complete * ev ;
6508+ struct hci_ev_le_remote_feat_complete * ev = data ;
65356509 struct hci_conn * conn ;
65366510
6537- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_EXT_ADV_REPORT ,
6538- sizeof (* ev ));
6539- if (!ev )
6540- return ;
6541-
6542- BT_DBG ("%s status 0x%2.2x" , hdev -> name , ev -> status );
6511+ bt_dev_dbg (hdev , "status 0x%2.2x" , ev -> status );
65436512
65446513 hci_dev_lock (hdev );
65456514
@@ -6575,19 +6544,16 @@ static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev,
65756544 hci_dev_unlock (hdev );
65766545}
65776546
6578- static void hci_le_ltk_request_evt (struct hci_dev * hdev , struct sk_buff * skb )
6547+ static void hci_le_ltk_request_evt (struct hci_dev * hdev , void * data ,
6548+ struct sk_buff * skb )
65796549{
6580- struct hci_ev_le_ltk_req * ev ;
6550+ struct hci_ev_le_ltk_req * ev = data ;
65816551 struct hci_cp_le_ltk_reply cp ;
65826552 struct hci_cp_le_ltk_neg_reply neg ;
65836553 struct hci_conn * conn ;
65846554 struct smp_ltk * ltk ;
65856555
6586- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_LTK_REQ , sizeof (* ev ));
6587- if (!ev )
6588- return ;
6589-
6590- BT_DBG ("%s handle 0x%4.4x" , hdev -> name , __le16_to_cpu (ev -> handle ));
6556+ bt_dev_dbg (hdev , "handle 0x%4.4x" , __le16_to_cpu (ev -> handle ));
65916557
65926558 hci_dev_lock (hdev );
65936559
@@ -6655,18 +6621,15 @@ static void send_conn_param_neg_reply(struct hci_dev *hdev, u16 handle,
66556621 & cp );
66566622}
66576623
6658- static void hci_le_remote_conn_param_req_evt (struct hci_dev * hdev ,
6624+ static void hci_le_remote_conn_param_req_evt (struct hci_dev * hdev , void * data ,
66596625 struct sk_buff * skb )
66606626{
6661- struct hci_ev_le_remote_conn_param_req * ev ;
6627+ struct hci_ev_le_remote_conn_param_req * ev = data ;
66626628 struct hci_cp_le_conn_param_req_reply cp ;
66636629 struct hci_conn * hcon ;
66646630 u16 handle , min , max , latency , timeout ;
66656631
6666- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_REMOTE_CONN_PARAM_REQ ,
6667- sizeof (* ev ));
6668- if (!ev )
6669- return ;
6632+ bt_dev_dbg (hdev , "handle 0x%4.4x" , __le16_to_cpu (ev -> handle ));
66706633
66716634 handle = le16_to_cpu (ev -> handle );
66726635 min = le16_to_cpu (ev -> interval_min );
@@ -6718,17 +6681,12 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
67186681 hci_send_cmd (hdev , HCI_OP_LE_CONN_PARAM_REQ_REPLY , sizeof (cp ), & cp );
67196682}
67206683
6721- static void hci_le_direct_adv_report_evt (struct hci_dev * hdev ,
6684+ static void hci_le_direct_adv_report_evt (struct hci_dev * hdev , void * data ,
67226685 struct sk_buff * skb )
67236686{
6724- struct hci_ev_le_direct_adv_report * ev ;
6687+ struct hci_ev_le_direct_adv_report * ev = data ;
67256688 int i ;
67266689
6727- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_DIRECT_ADV_REPORT ,
6728- sizeof (* ev ));
6729- if (!ev )
6730- return ;
6731-
67326690 if (!hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_DIRECT_ADV_REPORT ,
67336691 flex_array_size (ev , info , ev -> num )))
67346692 return ;
@@ -6750,17 +6708,13 @@ static void hci_le_direct_adv_report_evt(struct hci_dev *hdev,
67506708 hci_dev_unlock (hdev );
67516709}
67526710
6753- static void hci_le_phy_update_evt (struct hci_dev * hdev , struct sk_buff * skb )
6711+ static void hci_le_phy_update_evt (struct hci_dev * hdev , void * data ,
6712+ struct sk_buff * skb )
67546713{
6755- struct hci_ev_le_phy_update_complete * ev ;
6714+ struct hci_ev_le_phy_update_complete * ev = data ;
67566715 struct hci_conn * conn ;
67576716
6758- ev = hci_le_ev_skb_pull (hdev , skb , HCI_EV_LE_PHY_UPDATE_COMPLETE ,
6759- sizeof (* ev ));
6760- if (ev )
6761- return ;
6762-
6763- BT_DBG ("%s status 0x%2.2x" , hdev -> name , ev -> status );
6717+ bt_dev_dbg (hdev , "status 0x%2.2x" , ev -> status );
67646718
67656719 if (ev -> status )
67666720 return ;
@@ -6778,59 +6732,102 @@ static void hci_le_phy_update_evt(struct hci_dev *hdev, struct sk_buff *skb)
67786732 hci_dev_unlock (hdev );
67796733}
67806734
6781- static void hci_le_meta_evt (struct hci_dev * hdev , void * data ,
6782- struct sk_buff * skb )
6783- {
6784- struct hci_ev_le_meta * ev = data ;
6785-
6786- switch (ev -> subevent ) {
6787- case HCI_EV_LE_CONN_COMPLETE :
6788- hci_le_conn_complete_evt (hdev , skb );
6789- break ;
6790-
6791- case HCI_EV_LE_CONN_UPDATE_COMPLETE :
6792- hci_le_conn_update_complete_evt (hdev , skb );
6793- break ;
6735+ #define HCI_LE_EV_VL (_op , _func , _min_len , _max_len ) \
6736+ [_op] = { \
6737+ .func = _func, \
6738+ .min_len = _min_len, \
6739+ .max_len = _max_len, \
6740+ }
67946741
6795- case HCI_EV_LE_ADVERTISING_REPORT :
6796- hci_le_adv_report_evt (hdev , skb );
6797- break ;
6742+ #define HCI_LE_EV (_op , _func , _len ) \
6743+ HCI_LE_EV_VL(_op, _func, _len, _len)
67986744
6799- case HCI_EV_LE_REMOTE_FEAT_COMPLETE :
6800- hci_le_remote_feat_complete_evt (hdev , skb );
6801- break ;
6745+ #define HCI_LE_EV_STATUS (_op , _func ) \
6746+ HCI_LE_EV(_op, _func, sizeof(struct hci_ev_status))
68026747
6803- case HCI_EV_LE_LTK_REQ :
6804- hci_le_ltk_request_evt (hdev , skb );
6805- break ;
6748+ /* Entries in this table shall have their position according to the subevent
6749+ * opcode they handle so the use of the macros above is recommend since it does
6750+ * attempt to initialize at its proper index using Designated Initializers that
6751+ * way events without a callback function can be ommited.
6752+ */
6753+ static const struct hci_le_ev {
6754+ void (* func )(struct hci_dev * hdev , void * data , struct sk_buff * skb );
6755+ u16 min_len ;
6756+ u16 max_len ;
6757+ } hci_le_ev_table [U8_MAX + 1 ] = {
6758+ /* [0x01 = HCI_EV_LE_CONN_COMPLETE] */
6759+ HCI_LE_EV (HCI_EV_LE_CONN_COMPLETE , hci_le_conn_complete_evt ,
6760+ sizeof (struct hci_ev_le_conn_complete )),
6761+ /* [0x02 = HCI_EV_LE_ADVERTISING_REPORT] */
6762+ HCI_LE_EV_VL (HCI_EV_LE_ADVERTISING_REPORT , hci_le_adv_report_evt ,
6763+ sizeof (struct hci_ev_le_advertising_report ),
6764+ HCI_MAX_EVENT_SIZE ),
6765+ /* [0x03 = HCI_EV_LE_CONN_UPDATE_COMPLETE] */
6766+ HCI_LE_EV (HCI_EV_LE_CONN_UPDATE_COMPLETE ,
6767+ hci_le_conn_update_complete_evt ,
6768+ sizeof (struct hci_ev_le_conn_update_complete )),
6769+ /* [0x04 = HCI_EV_LE_REMOTE_FEAT_COMPLETE] */
6770+ HCI_LE_EV (HCI_EV_LE_REMOTE_FEAT_COMPLETE ,
6771+ hci_le_remote_feat_complete_evt ,
6772+ sizeof (struct hci_ev_le_remote_feat_complete )),
6773+ /* [0x05 = HCI_EV_LE_LTK_REQ] */
6774+ HCI_LE_EV (HCI_EV_LE_LTK_REQ , hci_le_ltk_request_evt ,
6775+ sizeof (struct hci_ev_le_ltk_req )),
6776+ /* [0x06 = HCI_EV_LE_REMOTE_CONN_PARAM_REQ] */
6777+ HCI_LE_EV (HCI_EV_LE_REMOTE_CONN_PARAM_REQ ,
6778+ hci_le_remote_conn_param_req_evt ,
6779+ sizeof (struct hci_ev_le_remote_conn_param_req )),
6780+ /* [0x0a = HCI_EV_LE_ENHANCED_CONN_COMPLETE] */
6781+ HCI_LE_EV (HCI_EV_LE_ENHANCED_CONN_COMPLETE ,
6782+ hci_le_enh_conn_complete_evt ,
6783+ sizeof (struct hci_ev_le_enh_conn_complete )),
6784+ /* [0x0b = HCI_EV_LE_DIRECT_ADV_REPORT] */
6785+ HCI_LE_EV_VL (HCI_EV_LE_DIRECT_ADV_REPORT , hci_le_direct_adv_report_evt ,
6786+ sizeof (struct hci_ev_le_direct_adv_report ),
6787+ HCI_MAX_EVENT_SIZE ),
6788+ /* [0x0c = HCI_EV_LE_PHY_UPDATE_COMPLETE] */
6789+ HCI_LE_EV (HCI_EV_LE_PHY_UPDATE_COMPLETE , hci_le_phy_update_evt ,
6790+ sizeof (struct hci_ev_le_phy_update_complete )),
6791+ /* [0x0d = HCI_EV_LE_EXT_ADV_REPORT] */
6792+ HCI_LE_EV_VL (HCI_EV_LE_EXT_ADV_REPORT , hci_le_ext_adv_report_evt ,
6793+ sizeof (struct hci_ev_le_ext_adv_report ),
6794+ HCI_MAX_EVENT_SIZE ),
6795+ /* [0x12 = HCI_EV_LE_EXT_ADV_SET_TERM] */
6796+ HCI_LE_EV (HCI_EV_LE_EXT_ADV_SET_TERM , hci_le_ext_adv_term_evt ,
6797+ sizeof (struct hci_evt_le_ext_adv_set_term )),
6798+ };
68066799
6807- case HCI_EV_LE_REMOTE_CONN_PARAM_REQ :
6808- hci_le_remote_conn_param_req_evt (hdev , skb );
6809- break ;
6800+ static void hci_le_meta_evt (struct hci_dev * hdev , void * data ,
6801+ struct sk_buff * skb )
6802+ {
6803+ struct hci_ev_le_meta * ev = data ;
6804+ const struct hci_le_ev * subev ;
68106805
6811- case HCI_EV_LE_DIRECT_ADV_REPORT :
6812- hci_le_direct_adv_report_evt (hdev , skb );
6813- break ;
6806+ bt_dev_dbg (hdev , "subevent 0x%2.2x" , ev -> subevent );
68146807
6815- case HCI_EV_LE_PHY_UPDATE_COMPLETE :
6816- hci_le_phy_update_evt ( hdev , skb );
6817- break ;
6808+ subev = & hci_le_ev_table [ ev -> subevent ];
6809+ if (! subev -> func )
6810+ return ;
68186811
6819- case HCI_EV_LE_EXT_ADV_REPORT :
6820- hci_le_ext_adv_report_evt (hdev , skb );
6821- break ;
6812+ if (skb -> len < subev -> min_len ) {
6813+ bt_dev_err (hdev , "unexpected subevent 0x%2.2x length: %u < %u" ,
6814+ ev -> subevent , skb -> len , subev -> min_len );
6815+ return ;
6816+ }
68226817
6823- case HCI_EV_LE_ENHANCED_CONN_COMPLETE :
6824- hci_le_enh_conn_complete_evt (hdev , skb );
6825- break ;
6818+ /* Just warn if the length is over max_len size it still be
6819+ * possible to partially parse the event so leave to callback to
6820+ * decide if that is acceptable.
6821+ */
6822+ if (skb -> len > subev -> max_len )
6823+ bt_dev_warn (hdev , "unexpected subevent 0x%2.2x length: %u > %u" ,
6824+ ev -> subevent , skb -> len , subev -> max_len );
68266825
6827- case HCI_EV_LE_EXT_ADV_SET_TERM :
6828- hci_le_ext_adv_term_evt ( hdev , skb );
6829- break ;
6826+ data = hci_le_ev_skb_pull ( hdev , skb , ev -> subevent , subev -> min_len );
6827+ if (! data )
6828+ return ;
68306829
6831- default :
6832- break ;
6833- }
6830+ subev -> func (hdev , data , skb );
68346831}
68356832
68366833static bool hci_get_cmd_complete (struct hci_dev * hdev , u16 opcode ,
0 commit comments