- join->local_pt.user_data = &netif;
- join->local_pt.sm = pt->sm;
- join->local_pt.state = 0;
- vsfsm_pt_entry(pt);
- if (3 == param->argc)
- {
- err = bcm_wifi_join(&join->local_pt, evt, &join->cur_status,
- param->argv[1], BCM_AUTHTYPE_WPA2_AES_PSK,
- (const uint8_t *)param->argv[2],
- strlen(param->argv[2]));
- }
- else
- {
- err = bcm_wifi_join(&join->local_pt, evt, &join->cur_status,
- param->argv[1], BCM_AUTHTYPE_OPEN, NULL, 0);
- }
- if (err < 0)
- {
- vsfshell_printf(output_pt, "Fail to join %s" VSFSHELL_LINEEND,
- param->argv[1]);
- goto handler_thread_end;
- }
- else if (join->cur_status != 0)
- {
- // process join status change, non-block code here
- }
- if (err != 0) return err;
-
- vsfshell_printf(output_pt, "%s connected" VSFSHELL_LINEEND, param->argv[1]);
-
- // start dhcp
- memset(&dhcp, 0, sizeof(dhcp));
- vsfsm_sem_init(&dhcp.update_sem, 0, VSFSM_EVT_USER_LOCAL);
- vsfip_dhcp_start(&netif, &dhcp);
- if (vsfsm_sem_pend(&dhcp.update_sem, pt->sm))
- {
- vsfsm_pt_wfe(pt, VSFSM_EVT_USER_LOCAL);
- }
- vsfshell_printf(output_pt, "dhcp update:" VSFSHELL_LINEEND);
- vsfshell_printf(output_pt, "IP: %d:%d:%d:%d" VSFSHELL_LINEEND,
- netif.ipaddr.addr.s_addr_buf[0], netif.ipaddr.addr.s_addr_buf[1],
- netif.ipaddr.addr.s_addr_buf[2], netif.ipaddr.addr.s_addr_buf[3]);
- vsfshell_printf(output_pt, "subnet: %d:%d:%d:%d" VSFSHELL_LINEEND,
- netif.netmask.addr.s_addr_buf[0], netif.netmask.addr.s_addr_buf[1],
- netif.netmask.addr.s_addr_buf[2], netif.netmask.addr.s_addr_buf[3]);
- vsfshell_printf(output_pt, "gateway: %d:%d:%d:%d" VSFSHELL_LINEEND,
- netif.gateway.addr.s_addr_buf[0], netif.gateway.addr.s_addr_buf[1],
- netif.gateway.addr.s_addr_buf[2], netif.gateway.addr.s_addr_buf[3]);
- // discover
- dhcp->ipaddr.size = 0;
- err = vsfip_dhcp_init_msg(dhcp, (uint8_t)VSFIP_DHCPOP_DISCOVER);
- if (err < 0)
- {
- goto cleanup;
- }
- vsfip_dhcp_end_opt(dhcp);
- dhcp->sockaddr.sin_addr.addr.s_addr = 0xFFFFFFFF;
- dhcp->caller_pt.state = 0;
- vsfsm_pt_entry(pt);
- err = vsfip_udp_send(&dhcp->caller_pt, evt, dhcp->so, &dhcp->sockaddr,
- dhcp->outbuffer);
- if (err < 0) {vsfip_buffer_release(dhcp->outbuffer); goto cleanup;}
- else if (err) return err;
- vsfip_buffer_release(dhcp->outbuffer);
-
- // wait OFFER
- dhcp->so->timeout_ms = 30000;
- dhcp->sockaddr.sin_addr.addr.s_addr = VSFIP_IPADDR_ANY;
- dhcp->caller_pt.state = 0;
- vsfsm_pt_entry(pt);
- err = vsfip_udp_recv(&dhcp->caller_pt, evt, dhcp->so, &dhcp->sockaddr,
- &dhcp->inbuffer);
- if (err > 0) return err; else if (err < 0) goto cleanup; else
- {
- // parse OFFER
- head = (struct vsfip_dhcphead_t *)dhcp->inbuffer->app.buffer;
- if ((head->op != VSFIP_DHCP_TOCLIENT) ||
- memcmp(head->chaddr, netif->macaddr.addr.s_addr_buf,
- netif->macaddr.size) ||
- (head->xid != dhcp->xid))
- {
- vsfip_buffer_release(dhcp->inbuffer);
- goto cleanup;
- }
-
- optlen = vsfip_dhcp_get_opt(dhcp->inbuffer, VSFIP_DHCPOPT_MSGTYPE,
- &optptr);
- if ((optlen != VSFIP_DHCPOPT_MSGTYPE_LEN) ||
- (optptr[0] != VSFIP_DHCPOP_OFFER))
- {
- vsfip_buffer_release(dhcp->inbuffer);
- goto cleanup;
- }
-
- dhcp->ipaddr.size = 4;
- dhcp->ipaddr.addr.s_addr = head->yiaddr;
- vsfip_buffer_release(dhcp->inbuffer);
- }