soonisys
www.soonisys.comdocs.soonisys.com
nRF9160 M.2 Module
nRF9160 M.2 Module
  • PRODUCTS DETAIL
    • nRF9160 M.2 Module
    • nRF9160 M.2 Development Kit
  • DEVELOPMENT
    • Getting Started-SDK v2.3.0
    • Getting Started-Legacy
      • Installation
      • Hello World - Sample
      • Create Project
      • Cat-M1 + UDP
      • Serial LTE Modem
    • Resources
    • Sim Cards
Powered by GitBook
On this page
  • 1. Preparations
  • 2. Create Project
  • 3. Source Codes
  • 3.1 src/main.c
  • 3.2 CMakeLists.txt
  • 3.3 prj.conf
  • 4. Build and Debug
  1. DEVELOPMENT
  2. Getting Started-Legacy

Cat-M1 + UDP

Test Simple UDP send/recv using LTE Cat-M.1

Let's send and recv UDP packet to soonisys's echo server.

We provide two free UDP test servers. "please don't attack our free servers...T.T"

Normal UDP echo server

The server simply sends back the received packet.

IPv4 - Address: 3.37.91.140 Port: 39633

Increase first byte UDP server

The server increase(+1) the first byte of the packet and sends it back.

IPv4 - Address: 3.37.91.140 Port: 39634

ex> device send:A1 B3 12 03 -> server send back:A2 B3 12 03

We will use 'Increase first byte' server to test UDP.

The echo server service is closed.

1. Preparations

  • nRF9160 M.2 Development Kit

  • LTE-M Nano-Simcard(We use 'things mobile' sim card)

2. Create Project

See Create Project.

Create project named 'mySooniUDP'. (You can choose any name)

3. Source Codes

3.1 src/main.c


#include <zephyr.h>
#include <zephyr/types.h>
#include <sys/printk.h>

#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>

#include <modem/lte_lc.h>
#include <net/socket.h>

#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>

#define SERVER_ADDR    "52.78.123.53"
#define SERVER_PORT    39634 // server increase first byte

static int sock;
static struct pollfd fds;
static struct sockaddr_storage server_addr;
static uint8_t tx_buf[512]; // we have a lot of ram space!!!!
static uint8_t rx_buf[512]; // me too

// return 0: we got the packet
// return -EAGAIN : no packet
static int wait(int timeout)
{
    int ret = poll(&fds, 1, timeout);
    if (ret == 0) return -EAGAIN; // no packet
    
    if (ret < 0) 
    {
            printk("@modem.wait:poll err=%d\n", errno);
            return -errno;
    }

    if ((fds.revents & POLLERR) == POLLERR) {
            printk("@modem.wait:POLLERR\n");
            return -EIO;
    }

    if ((fds.revents & POLLNVAL) == POLLNVAL) {
            printk("@modem.wait:POLLNVAL\n");
            return -EBADF;
    }

    if ((fds.revents & POLLIN) != POLLIN) return -EAGAIN;

    return 0; // packet exsist
}

// return -1 : error
// return 0  :no packet
// return >0 :recv packet size
int udp_recv(uint8_t *buf, int maxlen, int timeout_ms)
{
    int ret;
    
    if(maxlen <= 0) return -1; // parameter error:maxlen must be larger then 0
    if(timeout_ms <= 0) return -1; // parameter error:timeout_ms must be larger then 0

    ret = wait(timeout_ms);
    if (ret < 0) 
    {
        if (ret == -EAGAIN) return 0; // no packet
        printk("@modem.recv:wait err=%d\n", ret);
        return ret; // error on 'wait'
    }

    ret = recv(sock, buf, maxlen, MSG_DONTWAIT);
    if (ret < 0) 
    {
        if (errno == EAGAIN || errno == EWOULDBLOCK) return 0;
        else 
        {
            printk("@modem.recv:recv err=%d\n", ret);
            return ret;
        }
    }
    
    if (ret == 0) return 0; // no packet

    return ret; // recv length
}

// return:sent bytes
int udp_send(uint8_t *buf, int len)
{
    int ret;
    ret = send(sock, buf, len, 0); 
    if (ret < 0) 
    {
        printk("@modem.send:err.%d\n", errno);
    }
    return ret;
}

void main()
{
    int err, firstByte;
    int tx_ret, rx_ret;
    struct sockaddr_in *server4 = ((struct sockaddr_in *)&server_addr);

    printk("\n****** Hello. GettingStarted - mySooniUDP  ******\n");

    // #1. LTE link
    printk("lte:init and connect...\n"); // takes about 10~30seconds
    err = lte_lc_init_and_connect();
    if (err)
    {
         printk("@lte:error=%d\n", err);
         return;
    }
    printk("lte:connected.\n");

    // #2. UDP Socket
    // address parse
    server4->sin_family = AF_INET;
    server4->sin_port = htons((uint16_t)SERVER_PORT);
    inet_pton(AF_INET, SERVER_ADDR, &server4->sin_addr);    

    // socket create
    printk("socket:create...\n");
    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock < 0)
    {
        printk("@socket:create err=%d\n", errno);
        (void)close(sock); 
        return;
    }
    printk("socket:create ok.\n");
    
    // socket connect
    printk("socket:connect...\n");
    err = connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr_in)); 
    if(err != 0)
    {
        printk("@socket:connect err=%d\n", errno);
        (void)close(sock); 
        return;
    }
    printk("socket:connect ok.\n");
    
    /* Initialize FDS, for poll. */
    fds.fd = sock;
    fds.events = POLLIN;
    
    
    printk("let's send/recv packet\n");

    // #3. while
    firstByte = 0;
    while(true)
    {
        tx_buf[0] = (uint8_t)firstByte;
        rx_buf[0] = 0;
        
        printk("packet-%d:send at %u\n", firstByte, k_uptime_get_32());
        tx_ret = udp_send(tx_buf, 4);       
        rx_ret = udp_recv(rx_buf, 512, 5000);
        
        if((tx_ret > 0) && (rx_ret > 0))
        {
            tx_buf[0]++;
            if(tx_buf[0] == rx_buf[0]) printk("packet-%d:recv at %u, okay\n", firstByte, k_uptime_get_32());
            else printk("packet-%d:recv at %u, wrong\n", firstByte, k_uptime_get_32());
        }
        else
        {
            printk("@packet-%d:error\n", firstByte);
            // do something for exception.
        }
        
        firstByte++;
        printk("sleep:8000ms...\n");
        k_msleep(8000);
    }
}

3.2 CMakeLists.txt

CMakeLists.txt
#
# Copyright (c) 2020 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

cmake_minimum_required(VERSION 3.13.1)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(mySooniUDP)

# SOURCE FILES
target_sources(app PRIVATE src/main.c)

3.3 prj.conf

prj.conf
#
# Copyright (c) 2020 Nordic Semiconductor ASA
#
# SPDX-License-Identiier: LicenseRef-Nordic-5-Clause
#

# General config
CONFIG_NEWLIB_LIBC=y
CONFIG_HW_STACK_PROTECTION=y
CONFIG_SERIAL=y

# GPIO
CONFIG_GPIO=y

# LTE link control
CONFIG_LTE_LINK_CONTROL=y
CONFIG_LTE_AUTO_INIT_AND_CONNECT=n
CONFIG_LTE_NETWORK_MODE_LTE_M=y
CONFIG_LTE_NETWORK_USE_FALLBACK=n

# Network
CONFIG_NETWORKING=y
CONFIG_NET_NATIVE=n
CONFIG_NET_SOCKETS=y
CONFIG_NET_UDP=y
CONFIG_NET_SOCKETS_OFFLOAD=y
CONFIG_NET_SOCKETS_POSIX_NAMES=y

# Modem library
CONFIG_NRF_MODEM_LIB=y
CONFIG_NRF_MODEM_LIB_TRACE_ENABLED=n

# Heap and stacks
CONFIG_HEAP_MEM_POOL_SIZE=2048
CONFIG_MAIN_STACK_SIZE=4096
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

PreviousCreate ProjectNextSerial LTE Modem

Last updated 2 years ago

4.

Build and Debug