| 657 | #endif |
| 658 | |
| 659 | int at_bind(int socket, const struct sockaddr *name, socklen_t namelen) |
| 660 | { |
| 661 | struct at_socket *sock = RT_NULL; |
| 662 | struct at_device *device = RT_NULL; |
| 663 | ip_addr_t input_ipaddr, local_ipaddr; |
| 664 | uint16_t port = 0; |
| 665 | |
| 666 | if (name == NULL || namelen == 0) |
| 667 | { |
| 668 | rt_set_errno(EINVAL); |
| 669 | return -1; |
| 670 | } |
| 671 | |
| 672 | sock = at_get_socket(socket); |
| 673 | if (sock == RT_NULL) |
| 674 | { |
| 675 | rt_set_errno(ENXIO); |
| 676 | return -1; |
| 677 | } |
| 678 | |
| 679 | /* get current device ip address */ |
| 680 | device = (struct at_device *) sock->device; |
| 681 | ip_addr_copy(local_ipaddr, device->netdev->ip_addr); |
| 682 | |
| 683 | /* prase ip address and port from sockaddr structure */ |
| 684 | socketaddr_to_ipaddr_port(name, &input_ipaddr, &port); |
| 685 | |
| 686 | /* input ip address is different from device ip address */ |
| 687 | if (ip_addr_cmp(&input_ipaddr, &local_ipaddr) != 0) |
| 688 | { |
| 689 | struct at_socket *new_sock = RT_NULL; |
| 690 | struct at_device *new_device = RT_NULL; |
| 691 | enum at_socket_type type = sock->type; |
| 692 | |
| 693 | /* close old socket */ |
| 694 | if (at_closesocket(socket) < 0) |
| 695 | { |
| 696 | free_socket(sock); |
| 697 | rt_set_errno(EIO); |
| 698 | return -1; |
| 699 | } |
| 700 | |
| 701 | extern struct at_device *at_device_get_by_ipaddr(ip_addr_t *ip_addr); |
| 702 | new_device = at_device_get_by_ipaddr(&input_ipaddr); |
| 703 | if (new_device == RT_NULL) |
| 704 | { |
| 705 | rt_set_errno(EHOSTUNREACH); |
| 706 | return -1; |
| 707 | } |
| 708 | |
| 709 | /* allocate new socket */ |
| 710 | new_sock = alloc_socket_by_device(new_device, type); |
| 711 | if (new_sock == RT_NULL) |
| 712 | { |
| 713 | rt_set_errno(EIO); |
| 714 | return -1; |
| 715 | } |
| 716 | new_sock->type = type; |
nothing calls this directly
no test coverage detected