How can I return info from a callback?

Dan Williams dcbw at redhat.com
Mon Jul 25 09:15:48 PDT 2016


On Fri, 2016-07-22 at 17:27 -0400, Avery Rozar wrote:
> I wrote a class to get all the available bands for a given wireless
> interface. I add a callback function to the socket and send it.
> Inside my callback function I parse for the available bands and print
> them to the console.
> 
> How would I return a vector or something else to be used in the class
> that is calling the class to get the bands? Am I looking at this
> wrong? I can't get this info in nl_recvmsgs_default can I?
> 
> 
> Channel Selection Class:
> 
> int fs_channelSelection::selectChannels(unsigned int
> *networkDeviceId) {
>     fs_nl80211 *nl80211 = new fs_nl80211;
>     vector<uint32_t> band_list;
>     band_list = nl80211->getBands(networkDeviceId);
> }
> 
> 
> fs_nls80211 Class:
> 
> vector<uint32_t> fs_nl80211::getBands(unsigned int *networkDeviceId)
> {
>     // omit code for brevity
> 
>     // add callback info to the netlink socket
>     nl_socket_modify_cb((nl_sock *) netlink_sk, NL_CB_VALID,
> NL_CB_CUSTOM, getBandsCallback, NULL);

The NULL here is the key; it's a void* that's passed directly to
getBandsCallback().  So you'd create some structure to pass information
back and forth at the top of getBands(), and then pass a pointer to
that structure as the last argument to nl_socket_modify_cb().

Then in getBandsCallback() you'll get that pointer as the "void*"
argument, and you populate that structure with whatever you want to
pass back.  Then when control returns to getBands() the structure will
be populated and you'll have the info you want.

Obviously, keep an eye on memory/object ownership and be sure to
release the memory from the structure (and its members) when
appropriate.

Dan

>     // construct the message to nlcore
>     genlmsg_put((nl_msg *) netlink_msg, 0, NL_AUTO_SEQ, nl80211_id,
> 0,
> 0, NL80211_CMD_GET_WIPHY, 0);
>     NLA_PUT_U32((nl_msg *) netlink_msg, NL80211_ATTR_IFINDEX,
> *networkDeviceId);
> 
>     // send the message to netlink socket
>     nl_send_auto((nl_sock *) netlink_sk, (nl_msg *) netlink_msg);
> 
>     // receive the message
>     nl_recvmsgs_default((nl_sock *) netlink_sk);
>     nl_wait_for_ack((nl_sock *) netlink_sk);
> }
> 
> 
> getBandsCallback function:
> 
> static int getBandsCallback(struct nl_msg *msg, void *args) {
>     // omit code for brevity
> 
>     struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
>     vector<uint32_t> band_list;
> 
>     // omit code for brevity
>     // omit code for brevity
> 
>                     if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
>                         continue;
>                     freq =
> nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
>                     band_list.push_back(freq);
> 
>     // omit code for brevity
> 
>     // I'd like to be able to do this in the Channel Selection Class:
>     for(auto const& value: band_list) {
>         cout << value << endl;
> 
>     }
> }
> 
> 
> Thank you,
> Avery Rozar
> 
> _______________________________________________
> libnl mailing list
> libnl at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/libnl



More information about the libnl mailing list