Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "ibrcommon/config.h"
00009 #include "ibrcommon/net/lowpansocket.h"
00010 #include <sys/socket.h>
00011 #include <errno.h>
00012 #include <sys/types.h>
00013 #include <netinet/in.h>
00014 #include <arpa/inet.h>
00015 #include <string.h>
00016 #include <stdlib.h>
00017
00018 #ifdef HAVE_LIBNL
00019 #include <netlink/route/link.h>
00020 #include <netlink/route/addr.h>
00021 #include <netlink/genl/genl.h>
00022 #include <netlink/genl/ctrl.h>
00023 #endif
00024
00025 extern "C" {
00026 #include "ibrcommon/net/ieee802154.h"
00027 #include "ibrcommon/net/nl802154.h"
00028 extern struct nla_policy ieee802154_policy[IEEE802154_ATTR_MAX + 1];
00029 };
00030
00031 namespace ibrcommon
00032 {
00033 lowpansocket::lowpansocket(u_char proto) throw (SocketException)
00034 {
00035
00036 if ((_socket = ::socket(PF_IEEE802154, SOCK_DGRAM, 0)) < 0)
00037 {
00038 throw SocketException("lowpansocket: cannot create listen socket");
00039 }
00040
00041 bzero(&_sockaddr, sizeof(_sockaddr));
00042 _sockaddr.family = AF_IEEE802154;
00043 _sockaddr.addr.addr_type = IEEE802154_ADDR_SHORT;
00044 }
00045
00046 lowpansocket::~lowpansocket()
00047 {
00048 shutdown();
00049 }
00050
00051 void lowpansocket::shutdown()
00052 {
00053 if (_socket == -1) return;
00054 ::close(_socket);
00055 _socket = -1;
00056 }
00057
00058 int lowpansocket::receive(char* data, size_t maxbuffer)
00059 {
00060 struct sockaddr_ieee802154 clientAddress;
00061 socklen_t clientAddressLength = sizeof(clientAddress);
00062
00063 int ret = recvfrom(_socket, data, maxbuffer, MSG_WAITALL, (struct sockaddr *) &clientAddress, &clientAddressLength);
00064 return ret;
00065 }
00066
00067 lowpansocket::peer::peer(lowpansocket &socket, const struct sockaddr_ieee802154 &dest, const unsigned int panid)
00068 : _socket(socket)
00069 {
00070 bzero(&_destaddress, sizeof(_destaddress));
00071 _destaddress.family = AF_IEEE802154;
00072 _destaddress.addr.addr_type = IEEE802154_ADDR_SHORT;
00073
00074 memcpy(&_destaddress.addr.short_addr, &dest.addr.short_addr, sizeof(_destaddress.addr.short_addr));
00075 _destaddress.addr.pan_id = panid;
00076 }
00077
00078 int lowpansocket::peer::send(const char *data, const size_t length)
00079 {
00080 ::connect(_socket._socket, (struct sockaddr *) &_destaddress, sizeof(_destaddress));
00081
00082
00083 return ::send(_socket._socket, data, length, 0);
00084 }
00085
00086 lowpansocket::peer lowpansocket::getPeer(const string address, const unsigned int panid)
00087 {
00088 struct sockaddr_ieee802154 destaddress;
00089
00090 destaddress.addr.short_addr = atoi(address.c_str());
00091 return lowpansocket::peer(*this, destaddress, panid);
00092 }
00093
00094 void lowpansocket::getAddress(struct ieee802154_addr *ret, const vinterface &iface)
00095 {
00096 #ifdef HAVE_LIBNL
00097 struct nl_handle *nl = nl_handle_alloc();
00098 unsigned char *buf = NULL;
00099 struct sockaddr_nl nla;
00100 struct nlattr *attrs[IEEE802154_ATTR_MAX+1];
00101 struct genlmsghdr *ghdr;
00102 struct nlmsghdr *nlh;
00103 struct nl_msg *msg;
00104 int family;
00105
00106 if (!nl)
00107 return;
00108
00109 genl_connect(nl);
00110
00111
00112 msg = nlmsg_alloc();
00113 family = genl_ctrl_resolve(nl, "802.15.4 MAC");
00114 genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_ECHO, IEEE802154_LIST_IFACE, 1);
00115 nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, iface.toString().c_str());
00116 nl_send_auto_complete(nl, msg);
00117 nlmsg_free(msg);
00118
00119
00120 nl_recv(nl, &nla, &buf, NULL);
00121 nlh = (struct nlmsghdr*)buf;
00122 genlmsg_parse(nlh, 0, attrs, IEEE802154_ATTR_MAX, ieee802154_policy);
00123 ghdr = (genlmsghdr*)nlmsg_data(nlh);
00124 if (!attrs[IEEE802154_ATTR_SHORT_ADDR] || !attrs[IEEE802154_ATTR_SHORT_ADDR])
00125 return;
00126
00127
00128 ret->addr_type = IEEE802154_ADDR_SHORT;
00129 ret->pan_id = nla_get_u16(attrs[IEEE802154_ATTR_PAN_ID]);
00130 ret->short_addr = nla_get_u16(attrs[IEEE802154_ATTR_SHORT_ADDR]);
00131
00132 free(buf);
00133 nl_close(nl);
00134 #endif
00135 }
00136 }