@@ -128,6 +128,20 @@ static void convert_ns_addr_to_mbed(SocketAddress *s_addr, const ns_address_t *n
128
128
s_addr->set_ip_bytes (ns_addr->address , NSAPI_IPv6);
129
129
}
130
130
131
+ static int8_t find_interface_by_address (const uint8_t target_addr[16 ])
132
+ {
133
+ for (int if_id = 1 ; if_id <= 127 ; if_id++) {
134
+ int i = 0 ;
135
+ uint8_t if_addr[16 ];
136
+ while (arm_net_address_list_get_next (if_id, &i, if_addr) == 0 ) {
137
+ if (memcmp (target_addr, if_addr, 16 ) == 0 ) {
138
+ return if_id;
139
+ }
140
+ }
141
+ }
142
+ return -1 ;
143
+ }
144
+
131
145
void * NanostackSocket::operator new (std::size_t sz) {
132
146
return MALLOC (sz);
133
147
}
@@ -693,17 +707,50 @@ nsapi_error_t NanostackInterface::setsockopt(void *handle, int level, int optnam
693
707
return NSAPI_ERROR_NO_SOCKET;
694
708
}
695
709
696
- nsapi_error_t ret;
697
-
698
710
NanostackLockGuard lock;
699
711
712
+ ns_ipv6_mreq_t ns_mreq;
713
+
714
+ if (level == NSAPI_SOCKET) {
715
+ switch (optname) {
716
+ case NSAPI_ADD_MEMBERSHIP:
717
+ case NSAPI_DROP_MEMBERSHIP: {
718
+ if (optlen != sizeof (nsapi_ip_mreq_t )) {
719
+ return NSAPI_ERROR_PARAMETER;
720
+ }
721
+ const nsapi_ip_mreq_t *imr = static_cast <const nsapi_ip_mreq_t *>(optval);
722
+
723
+ /* Check address types are IPv6, or unspecified for interface */
724
+ if (imr->imr_multiaddr .version != NSAPI_IPv6 ||
725
+ (imr->imr_interface .version != NSAPI_UNSPEC && imr->imr_interface .version != NSAPI_IPv6)) {
726
+ return NSAPI_ERROR_PARAMETER;
727
+ }
728
+
729
+ /* Convert all parameters to Nanostack native, and proceed with setsockopt */
730
+ memcpy (ns_mreq.ipv6mr_multiaddr , imr->imr_multiaddr .bytes , 16 );
731
+ if (imr->imr_interface .version == NSAPI_UNSPEC || memcmp (imr->imr_interface .bytes , ns_in6addr_any, 16 ) == 0 ) {
732
+ ns_mreq.ipv6mr_interface = 0 ;
733
+ } else {
734
+ // If this fails, Nanostack will itself fault the invalid -1 interface ID
735
+ ns_mreq.ipv6mr_interface = find_interface_by_address (imr->imr_interface .bytes );
736
+ }
737
+
738
+ level = SOCKET_IPPROTO_IPV6;
739
+ optname = optname == NSAPI_ADD_MEMBERSHIP ? SOCKET_IPV6_JOIN_GROUP : SOCKET_IPV6_LEAVE_GROUP;
740
+ optval = &ns_mreq;
741
+ optlen = sizeof ns_mreq;
742
+ break ;
743
+ }
744
+ default :
745
+ return NSAPI_ERROR_PARAMETER;
746
+ }
747
+ }
748
+
700
749
if (::socket_setsockopt (socket->socket_id , level, optname, optval, optlen) == 0 ) {
701
- ret = NSAPI_ERROR_OK;
750
+ return NSAPI_ERROR_OK;
702
751
} else {
703
- ret = NSAPI_ERROR_PARAMETER;
752
+ return NSAPI_ERROR_PARAMETER;
704
753
}
705
-
706
- return ret;
707
754
}
708
755
709
756
nsapi_error_t NanostackInterface::getsockopt (void *handle, int level, int optname, void *optval, unsigned *optlen)
0 commit comments