digidotcom / xbee_ansic_library

A collection of portable ANSI C code for communicating with Digi International's XBee wireless radio modules in API mode.
204 stars 116 forks source link

Not receving callbacks for socket frame in socket APIs #26

Closed Rutvij-dev closed 3 years ago

Rutvij-dev commented 4 years ago

Hi, I Am working on TCP/IP where i wanted to integrate Phy layer of Xbee3 in standard socket APIs for client side. To do so i took the reference from this link. For documentation i used Doxygen and header file while writing PAL layer for my hardware. Below is implementation is used for clubbing sockets api to xbee socket apis.

SOCKETS_Socket() maps to xbee_sock_create() SOCKETS_Recv() maps to xbee_sock_recv() SOCKETS_Send( ) maps to xbee_sock_send() SOCKETS_SetSockOpt maps to xbee_sock_option() SOCKETS_Close() maps to xbee_sock_close() SOCKETS_Connect maps to xbee_sock_connect

I have added frame dispatcher for every notification and given notify handler while creating socket.

#define XBEE_SOCK_FRAME_HANDLERS        { 0, 0, xbee_sock_frame_handler, NULL } //receive for every frame event

const xbee_dispatch_table_entry_t xbee_frame_handlers[] = {
    XBEE_FRAME_HANDLE_LOCAL_AT, //local side 
    XBEE_SOCK_FRAME_HANDLERS,
    XBEE_FRAME_TABLE_END
};

notify call back implementation is as per below

void notify_callback(xbee_sock_t socket,
                            uint8_t frame_type, uint8_t message)
{
#if XBEE_TX_DELIVERY_STR_BUF_SIZE > XBEE_SOCK_STR_BUF_SIZE
    char buffer[XBEE_TX_DELIVERY_STR_BUF_SIZE];
#else
    char buffer[XBEE_SOCK_STR_BUF_SIZE];
#endif

    switch (frame_type) {
    case XBEE_FRAME_TX_STATUS:          // message is an XBEE_TX_DELIVERY_xxx
        if (message != 0) {
            //printf("Socket 0x%04X: XBEE_TX_DELIVERY=%s\n",socket, xbee_tx_delivery_str(message, buffer));
        }
        break;

    case XBEE_FRAME_SOCK_STATE:         // message is an XBEE_SOCK_STATE_xxx
        printf("Socket 0x%04X: XBEE_SOCK_STATE=%s\n",
               socket, xbee_sock_state_str(message, buffer));
        break;

    case XBEE_FRAME_SOCK_CREATE_RESP:
    case XBEE_FRAME_SOCK_CONNECT_RESP:
    case XBEE_FRAME_SOCK_CLOSE_RESP:
    case XBEE_FRAME_SOCK_LISTEN_RESP:   // message is an XBEE_SOCK_STATUS_xxx
        if (message != 0) {
            printf("Socket 0x%04X: XBEE_SOCK_STATUS=%s\n",
                   socket, xbee_sock_status_str(message, buffer));
        }
        break;

    default:
        printf("Socket 0x%04X: unexpected frame_type 0x%02X, message 0x%02X\n",
               socket, frame_type, message);
    }
}

After initializing xbee module and going into API mode I am able to resolve FQDN and getting IP of remote host from its callback network is also available . But after creating socket i am not able to receive any callback which should provide xbee modules' socket status.

From the initial level debug i found that AT commands are properly executing from host to xbee module while every socket operations.

So how do i get the callbacks which states actual xbee's socket status ? I was unable to find any client side implementation from this lib, so could not debug further.

Thanks

tomlogic commented 4 years ago

If you remove the if (message != 0) wrapper from the XBEE_FRAME_SOCK_CREATE_RESP case, does it give you a SUCCESS response? You might also want to look at the xbee_netcat sample for code to open a socket and pass data to/from stdout/stdin.

Rutvij-dev commented 4 years ago

Hi, I tried with the mentioned example of xbee_netcat and modified a bit for my platform to remove windows related definitions. but unfortunately I'm facing the same issue.

After netcat_socket = xbee_sock_create(xbee, proto,netcat_sock_notify_cb); i received callback with frame 0x8a, and then not moving forward.

Below is the sequence of logs i am getting,

xbee_sock_frame_handler 0x88, Cellular module connected... xbee_sock_frame_handler 0x88, My IP is 10.117.118.127 xbee_sock_create: created socket 0x0037 xbee_sock_frame_handler 0x8a

I have created a sample server in Linux based system which i wanted to communicate to using socket API of xbee cellular module in LTE-M mode (not nb-iot). I have attached sample server code as well as modified xbee_netcat code with logs.

Furthermore i have XBEE_CELLULAR_ENABLED=1 is enabled.

Why callbacks are not being called ?

Thanks

xbee_logs.txt main.txt xbee_net.txt socket_server.txt

tomlogic commented 4 years ago

Frame 0x8A is a Modem Status frame, and the type may be important. You could add XBEE_FRAME_MODEM_STATUS_DEBUG to your frame table (at the end of the program) to see what the status is reporting.

If the board is resetting, it could be because you aren't providing enough power.

If it's indicating a connection, then it could be that you're creating your socket too soon and should wait for ATAI to be 0 (indicating that you're online).

But, you are calling xbee_sock_create() and that's successful -- it's giving you a socket handle of 0x0037. Af that point, you should CONNECT that socket and start using it for something. But for some reason your program isn't reaching NETCAT_STATE_CREATED.

Does netcat_sock_notify_cb() ever hit case XBEE_FRAME_SOCK_CREATE_RESP?

Ah, here's a possible problem:

static int initXBee(void)
{
  xbee_serial_t ser1;

Your xbee_dev_t will point to ser1 as the serial device, but you're declaring that on the stack of initXBee() and it will go away. Update that declaration to static xbee_serial_t ser1 or have ser1 declared outside of that function with the xbee_dev_t declaration.

Rutvij-dev commented 4 years ago

Hi, Form my side of debug i found that Currently my module has "1140b" firmware version. To support extended socket apis, i might need to go to the higher firmware version ?

This guide is from DIGI and it has firmware versions details.

I hope after doing upgrade i will be able to get the response from Xbee module for socket creation and will move ahed .

Is my understanding correct here ?

Thanks

tomlogic commented 4 years ago

I think your firmware is fine, based on seeing xbee_sock_create: created socket 0x0037 in your output. You are already getting a response on the socket creation.

Did you try fixing the declaration of ser1? And what Modem Status is coming in on that 0x8A frame?

Rutvij-dev commented 3 years ago

Hi, Yes i tried the solution but with no luck, then i went to my original suspect which was firmware upgrade. I upgraded the Xbee3's device as well as module's firmware using XCTU.

After upgrading to new firmware 'Firmware Version:11415' now I am able to capture callbacks of socket creation as well as of socket connect.

I suggest to upgrade Readme.txt or attach a doc to know which functionality is tested or supported to which version of firmware.

Thanks.

tomlogic commented 3 years ago

I'm sorry, that's correct. I should have recognized how old your firmware was. I thought the XBee was responding to the socket creation, and therefore had valid software for that feature. I'll leave this issue as a reminder to update sample/library documentation to indicate which release first had these frame types.

Rutvij-dev commented 3 years ago

Hi, I moved ahead with the above solution but while writing to xbee_sock_recv() , i could not find(or understand) any reference in xbee_netcat.c So any reference is available in order to write TCP recv function with extended socket ? I Need this function as i m integrating this with AWS freeRTOS.

Thanks

tomlogic commented 3 years ago

You need to write an xbee_sock_receive_fn that accepts the inbound data and places in into some sort of queue/buffer for retrieval by your xbee_sock_recv() function. I don’t have experience with AWS FreeRTOS, so I don’t know what native data structures you have available, but a simple circular/ring buffer appropriately sized would be the easiest for your TCP sockets. UDP would require a more complex data structure because you have to store individual datagrams with their sizes.

For example, in the xbee_netcat.c sample, netcat_sock_receive_cb() just takes the TCP data and prints it to stdout. Your version of this function should take the data and store it for later retrieval. Make sure your xbee_sock_recv() function returns the correct value to signal to the caller the difference between "no data available" and "socket is closed".

Rutvij-dev commented 3 years ago

Hi, Circular data structure is provided by xbee lib named xbee_cbuf.c , currently this is used with serial console prints. Can this be used ? Any suggestion ?

Thanks

tomlogic commented 3 years ago

Yes, you can make use of that library. I'm not sure, but it should be safe to run in a context where one task inserts data and another task removes it (single producer, single consumer). You want to make sure that one task only modifies the head, and the other task only modifies the tail.

Rutvij-dev commented 3 years ago

Hi, Thanks for the help.

Thanks