Chat freely about anything...

User avatar
By SomeDay54
#49796 I'm new to ESP8266 and have difficulties sending UDP multicast messages on AP interface and STATION interface: My send(s) only show up on AP interface. I verified this using wireshark on a computer connected to the ESP-AP and to the network. When connected to the ESP-AP both (!) UDP-packets show, otherwise no packet shows, regardless of and fully ignorant of wifi_set_broadcast_if.

I'll enclose my code below which is in parts a mixture of different concepts. I already tried different approaches but just can't get to see why it wouldn't work as I want.

  1. init
    • config uart
    • config wifi to STATIONAP_MODE + config wifi_set_broadcast_if
    • config connections (one for AP, separate one for STATION) and config tasks / timers / handlers
  2. timers
    • timer to check network state every second (predecessor / alternative to wifi_set_event_hander_cb)
    • timer to sporadically do "work", i.e. post a message to IdleTask (main work routine)
  3. IdleTask
    • send UDP message to a connection for AP and - if connected to a STATION - to another connection for STATION
  4. wifi_handle_event_cb (wifi_set_event_hander_cb)
    • initialize a connection whenever an IP for STATION has been received

Thanks in advance for any hint,

M.

Code:
Code: Select all// Copyright by SomeDay54
#include "ets_sys.h"
#include "osapi.h"
#include "user_interface.h"

#include "ip_addr.h"
#include "espconn.h"
#include "mem.h"

//default tasks (3 priority levels)
#define TopTaskPrio        2
#define TopTaskQueueLen    1

#define ActionTaskPrio        1
#define ActionTaskQueueLen    8

#define IdleTaskPrio        0
//#define IdleTaskQueueLen    1
#define IdleTaskQueueLen    10

#define MAX_BUF 1024

static void TopTask(os_event_t *events);
static void ActionTask(os_event_t *events);
static void IdleTask(os_event_t *events);

void ICACHE_FLASH_ATTR udp_Receive (void* arg);
void ICACHE_FLASH_ATTR udp_SendComplete (void* arg);
void ICACHE_FLASH_ATTR wifi_handle_event_cb(System_Event_t *evt);

os_event_t    TopTaskQueue[TopTaskQueueLen];
os_event_t    ActionTaskQueue[ActionTaskQueueLen];
os_event_t    IdleTaskQueue[IdleTaskQueueLen];

static int network = -1;
static os_timer_t network_timer;
static os_timer_t next_work_timer;

struct espconn udpCon;
struct espconn udpConAP;
ip_addr_t multicast_ip;
uint8 hostAddr[4];
char udpBuf[MAX_BUF+1];

void ICACHE_FLASH_ATTR network_check_ip(void)
{
   struct ip_info ipconfig;
   
   os_timer_disarm(&network_timer); // Disarm timer
   wifi_get_ip_info(STATION_IF, &ipconfig); // Get Wifi info
   
   if (wifi_station_get_connect_status() == STATION_GOT_IP && ipconfig.ip.addr != 0)
   { 

      os_printf("connected (%d.%d.%d.%d) !!! \r\n", hostAddr[0]=ip4_addr1(&ipconfig.ip.addr), hostAddr[1]=ip4_addr2(&ipconfig.ip.addr), hostAddr[2]=ip4_addr3(&ipconfig.ip.addr), hostAddr[3]=ip4_addr4(&ipconfig.ip.addr));
     
   }
   else if ((wifi_station_get_connect_status() == STATION_WRONG_PASSWORD ||
             wifi_station_get_connect_status() == STATION_NO_AP_FOUND ||
             wifi_station_get_connect_status() == STATION_CONNECT_FAIL)) {
      os_printf("connect fail (%d) !!! \r\n", wifi_station_get_connect_status());
   } else
   {
      os_printf("Waiting for IP...\n\r");
      if (network-- == -1000) {
         os_printf("No connection / no ip\n");
         // switch to ap
         network = 2;
         //wifi_set_opmode(STATION_MODE); // Force Station mode
         //wifi_station_set_auto_connect(TRUE);
      } else {
         //wifi_station_connect(); //should work automagically
         os_timer_setfn(&network_timer, (os_timer_func_t *)network_check_ip, NULL);
         os_timer_arm(&network_timer, 1000, 0);
      }
   }
}

/******************************************************************************
 * FunctionName : user_set_station_config
 * Description  : set the router info which ESP8266 station will connect to
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
user_set_station_config(void)
{
   // Wifi configuration
   char ssid[32] = "SSID";
   char password[64] = "PWD";
   struct station_config stationConf;
   
   os_memset(stationConf.ssid, 0, 32);
   os_memset(stationConf.password, 0, 64);
   //need not mac address
   stationConf.bssid_set = 0;
   
   wifi_set_opmode(STATIONAP_MODE); // Force Station+AP mode
   wifi_set_broadcast_if(STATIONAP_MODE);
   wifi_set_event_handler_cb(wifi_handle_event_cb);

   //Set ap settings
   os_memcpy(&stationConf.ssid, ssid, 32);
   os_memcpy(&stationConf.password, password, 64);
   //wifi_station_set_config(&stationConf);

   //set a timer to check whether got ip from router succeed or not.
   os_timer_disarm(&network_timer);
   os_timer_setfn(&network_timer, (os_timer_func_t *)network_check_ip, NULL);
   os_timer_arm(&network_timer, 1000, 0);
}

static void ICACHE_FLASH_ATTR TopTask(os_event_t *events){

}

static void ICACHE_FLASH_ATTR ActionTask(os_event_t *events){

}

static void ICACHE_FLASH_ATTR IdleTask(os_event_t *events){

    os_printf("GMA-Task\n");
    os_sprintf(udpBuf, "Packet ok\n");

    udpBuf[MAX_BUF]=0;
    espconn_sendto(&udpCon, udpBuf, MAX_BUF);
    if (network == 1) {
       espconn_sendto(&udpConAP, udpBuf, MAX_BUF);
    }

    //system_os_post(IdleTaskPrio, 0, 0); //add IdleTask back into queue
}

void ICACHE_FLASH_ATTR IdleTask2(void) {
    os_timer_disarm(&next_work_timer);
    system_os_post(IdleTaskPrio, 0, 0); //add IdleTask back into queue
    os_timer_setfn(&next_work_timer, (os_timer_func_t *)IdleTask2, NULL);
    os_timer_arm(&next_work_timer, 10000, 0);
}

void ICACHE_FLASH_ATTR udp_Receive (void* arg) {
    os_printf("UDP receive ..\n");
}

void ICACHE_FLASH_ATTR udp_SendComplete (void* arg) {
    os_printf("UDP sent ..\n");
}

void ICACHE_FLASH_ATTR init_tasks(){
    IP4_ADDR(&multicast_ip, 224, 0, 2, 9); // 224.0.2.9
    memset(&udpCon, 0, sizeof(udpCon));
    memset(&udpConAP, 0, sizeof(udpConAP));
    udpCon.type = ESPCONN_UDP;
    udpCon.state = ESPCONN_NONE;
    udpCon.proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp));
    udpCon.proto.udp->local_port = 1025;
    udpCon.proto.udp->remote_port = 6789;
    udpCon.proto.udp->remote_ip[0] = ip4_addr1(&multicast_ip);
    udpCon.proto.udp->remote_ip[1] = ip4_addr2(&multicast_ip);
    udpCon.proto.udp->remote_ip[2] = ip4_addr3(&multicast_ip);
    udpCon.proto.udp->remote_ip[3] = ip4_addr4(&multicast_ip);
    udpConAP.type = ESPCONN_UDP;
    udpConAP.state = ESPCONN_NONE;
    udpConAP.proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp));
    udpConAP.proto.udp->local_port = 1024;
    udpConAP.proto.udp->remote_port = 6789;
    udpConAP.proto.udp->remote_ip[0] = ip4_addr1(&multicast_ip);
    udpConAP.proto.udp->remote_ip[1] = ip4_addr2(&multicast_ip);
    udpConAP.proto.udp->remote_ip[2] = ip4_addr3(&multicast_ip);
    udpConAP.proto.udp->remote_ip[3] = ip4_addr4(&multicast_ip);
    espconn_regist_recvcb(&udpConAP, (espconn_recv_callback) ((void *)udp_Receive));   
    espconn_regist_sentcb(&udpConAP, (espconn_sent_callback) ((void *)udp_SendComplete));
    if (espconn_create(&udpConAP) == 0) {
       os_printf("UDP-Port AP ok\n");
    } else
       os_printf("UDP-Port AP error\n");

    os_printf("Initialisation Complete. Starting Tasks\n");
    //add tasks
    system_os_task(TopTask, TopTaskPrio, TopTaskQueue, TopTaskQueueLen);
    system_os_task(ActionTask, ActionTaskPrio, ActionTaskQueue, ActionTaskQueueLen);
    system_os_task(IdleTask, IdleTaskPrio, IdleTaskQueue, IdleTaskQueueLen);
    //after init done, start idle task loop
    system_os_post(IdleTaskPrio, 0, 0);
   
    os_timer_disarm(&next_work_timer);
    os_timer_setfn(&next_work_timer, (os_timer_func_t *)IdleTask2, NULL);
    os_timer_arm(&next_work_timer, 10000, 0);
}


void user_rf_pre_init(void)
{
}

void ICACHE_FLASH_ATTR wifi_handle_event_cb(System_Event_t *evt)
{  int state;

   os_printf("event %x\n", evt->event);
   switch (evt->event) {
      case EVENT_STAMODE_CONNECTED:
         os_printf("connect to ssid %s, channel %d\n",
               evt->event_info.connected.ssid,
               evt->event_info.connected.channel);
         break;
      case EVENT_STAMODE_DISCONNECTED:
         network=-1;
         os_printf("disconnect from ssid %s, reason %d\n",
               evt->event_info.disconnected.ssid,
               evt->event_info.disconnected.reason);
         espconn_igmp_leave((ip_addr_t *)hostAddr, &multicast_ip);
         state=espconn_delete(&udpCon);
         os_printf("udpCon deleted ret=%d\n", state);
         break;
      case EVENT_STAMODE_AUTHMODE_CHANGE:
         os_printf("mode: %d -> %d\n",
               evt->event_info.auth_change.old_mode,
               evt->event_info.auth_change.new_mode);
         break;
      case EVENT_STAMODE_GOT_IP:
         os_printf("ip:" IPSTR ",mask:" IPSTR ",gw:" IPSTR,
               IP2STR(&evt->event_info.got_ip.ip),
               IP2STR(&evt->event_info.got_ip.mask),
               IP2STR(&evt->event_info.got_ip.gw));
         os_printf("\n");
         hostAddr[0]=ip4_addr1(&evt->event_info.got_ip.ip.addr);
         hostAddr[1]=ip4_addr2(&evt->event_info.got_ip.ip.addr);
         hostAddr[2]=ip4_addr3(&evt->event_info.got_ip.ip.addr);
         hostAddr[3]=ip4_addr4(&evt->event_info.got_ip.ip.addr);
         udpCon.type = ESPCONN_UDP;
         udpCon.state = ESPCONN_NONE;
         //udpCon.proto.udp = (esp_udp *)os_zalloc(sizeof(esp_udp));
         udpCon.proto.udp->local_port = 1025;
         udpCon.proto.udp->remote_port = 6789;
         udpCon.proto.udp->remote_ip[0] = ip4_addr1(&multicast_ip);
         udpCon.proto.udp->remote_ip[1] = ip4_addr2(&multicast_ip);
         udpCon.proto.udp->remote_ip[2] = ip4_addr3(&multicast_ip);
         udpCon.proto.udp->remote_ip[3] = ip4_addr4(&multicast_ip);
         udpCon.proto.udp->local_ip[0] = hostAddr[0];
         udpCon.proto.udp->local_ip[1] = hostAddr[1];
         udpCon.proto.udp->local_ip[2] = hostAddr[2];
         udpCon.proto.udp->local_ip[3] = hostAddr[3];
         // if (wifi_set_broadcast_if(STATIONAP_MODE)) {
         if (wifi_set_broadcast_if(STATION_MODE)) {
            os_printf("broadcast to ap and station\n");
         } else {
            os_printf("broadcast to ap and station failed\n");
         }
         espconn_igmp_join((ip_addr_t *)hostAddr, &multicast_ip);
         espconn_regist_recvcb(&udpCon, (espconn_recv_callback) ((void *)udp_Receive));   
         espconn_regist_sentcb(&udpCon, (espconn_sent_callback) ((void *)udp_SendComplete));
         state=espconn_create(&udpCon);
         os_printf("udpCon created ret=%d\n", state);
         network=1;
         break;
      case EVENT_SOFTAPMODE_STACONNECTED:
         os_printf("station: " MACSTR "join, AID = %d\n",
               MAC2STR(evt->event_info.sta_connected.mac),
               evt->event_info.sta_connected.aid);
         break;
      case EVENT_SOFTAPMODE_STADISCONNECTED:
         os_printf("station: " MACSTR "leave, AID = %d\n",
               MAC2STR(evt->event_info.sta_disconnected.mac),
               evt->event_info.sta_disconnected.aid);
         break;
      default:
         break;
   }
}


/******************************************************************************
 * FunctionName : user_init
 * Description  : entry of user application, init user function here
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void user_init(void)
{   
    uart_div_modify(0, UART_CLK_FREQ / 115200);

    os_printf("SDK version:%s\n", system_get_sdk_version());

    user_set_station_config();

    os_printf("Post-Station\n");

    //system_init_done_cb(init_tasks);
    init_tasks();
}