Problem with MDC API

I am trying to use the MDC API for the FX30S but I am having some troubles and an error which is difficult to troubleshoot.
So I have followed these instructions:
https://docs.legato.io/15_08/c_mdc.html
And also these two:

github.com

legatoproject/legato-af/blob/e4e7835b5857fce2ebf2644db06ee7bb9b2f1205/apps/test/modemServices/mdc/mdcIntegrationTest_TX/mdcTestComp/mdcTest.c

/**
 * This module is for testing of the modemServices MDC component.
 *
 * You must issue the following commands:
 * @verbatim
   $ app start mdcTest
   @endverbatim
 *
 * By default, the profile used is LE_MDC_DEFAULT_PROFILE, and the APN is automatically set.
 * Some customize parameters can be set by creating a "/tmp/config.txt" file and fill a command
 * line with the syntax:
 * <profile number> <pdp_type> <apn> [<authentication_type> <username> <password>]
 * Where:
 *  - <profile number> is the profile number to be used (or "default" to use the default profile)
 *  - <pdp_type> if the packet data protocol to be used: "ipv4", "ipv6", or "ipv4v6"
 *  - <apn> is the APN to be used
 *  - <authentication_type> (optional): authentication requested: "auth_none" (default), pap",
 *  "chap", "pap-chap"
 *  - <username> (optional): username for authentication
 *  - <password> (optional): password for authentication

This file has been truncated. show original

The problem I am having is that this works (at times) and at times doesn`t work.
The problem seems to be with the handler which report a wrong status?
This is my code
static void SetNetworkConfiguration()
{
char ipAddr[100] = {0};
char gatewayAddr[100] = {0};
char dns1Addr[100] = {0};
char dns2Addr[100] = {0};
char systemCmd[200] = {0};
FILE* resolvFilePtr;
le_mdc_ConState_t state = LE_MDC_DISCONNECTED;
mode_t oldMask;

// Check the state
LE_ASSERT( le_mdc_GetSessionState(modemProfile, &state) == LE_OK );
LE_ASSERT( state == LE_MDC_CONNECTED );

// Get IP, gateway and DNS addresses for IPv4 or IPv6 connectivity
if ( le_mdc_IsIPv4(modemProfile) )
{
    LE_ASSERT(le_mdc_GetIPv4Address(modemProfile, ipAddr, sizeof(ipAddr)) == LE_OK);
    LE_INFO("%s", ipAddr);

    LE_ASSERT(le_mdc_GetIPv4GatewayAddress(modemProfile, gatewayAddr, sizeof(gatewayAddr))
                                                                                      == LE_OK);
    LE_INFO("%s", gatewayAddr);

    LE_ASSERT(le_mdc_GetIPv4DNSAddresses( modemProfile,
                                          dns1Addr, sizeof(dns1Addr),
                                          dns2Addr, sizeof(dns2Addr)) == LE_OK );
    LE_INFO("%s", dns1Addr);
    LE_INFO("%s", dns2Addr);

    snprintf(systemCmd, sizeof(systemCmd), "/sbin/route add default gw %s", gatewayAddr);
}
else if ( le_mdc_IsIPv6(modemProfile) )
{
    LE_ASSERT(le_mdc_GetIPv6Address(modemProfile, ipAddr, sizeof(ipAddr)) == LE_OK);
    LE_INFO("%s", ipAddr);

    LE_ASSERT(le_mdc_GetIPv6GatewayAddress(modemProfile, gatewayAddr, sizeof(gatewayAddr))
                                                                                      == LE_OK);
    LE_INFO("%s", gatewayAddr);

    LE_ASSERT(le_mdc_GetIPv6DNSAddresses( modemProfile,
                                          dns1Addr, sizeof(dns1Addr),
                                          dns2Addr, sizeof(dns2Addr)) == LE_OK );
    LE_INFO("%s", dns1Addr);
    LE_INFO("%s", dns2Addr);

    snprintf(systemCmd, sizeof(systemCmd), "/sbin/route -A inet6 add default gw %s",
                                            gatewayAddr);
}

sleep(5);

LE_DEBUG("%s", systemCmd);
LE_ASSERT( system(systemCmd) == 0 );

// allow fopen to create file with mode=644
oldMask = umask(022);

// open the resolver configuration
resolvFilePtr = fopen("/etc/resolv.conf", "w+");

if (resolvFilePtr == NULL)
{
    LE_ERROR("Unable to open resolv.conf: %m");
}
LE_ASSERT( resolvFilePtr != NULL );

LE_ASSERT( fprintf(resolvFilePtr, "nameserver %s\n", dns1Addr) > 0 );

if (dns2Addr[0] != '\0')
{
    LE_ASSERT( fprintf(resolvFilePtr, "nameserver %s\n", dns2Addr) > 0 );
}

LE_ASSERT( fclose(resolvFilePtr) == 0 );

// restore old mask
umask(oldMask);

}

static le_result_t ConnectModem(){
//create an handler for Data Connection state
char data[200];
char APN[11] = “telstra.wap”;
le_result_t rs;
LE_FATAL_IF(modemProfile == NULL, “Profile doesn t exist"); //set the PDP rs = le_mdc_SetPDP(modemProfile, LE_MDC_PDP_IPV4V6); LE_FATAL_IF(rs != LE_OK, "Couldn t set PDP.”);
//readback the PDP
le_mdc_Pdp_t ProfilePDP = le_mdc_GetPDP(modemProfile);
switch (ProfilePDP)
{
case LE_MDC_PDP_UNKNOWN:
LE_INFO(“PDP Unknown”);
break;
case LE_MDC_PDP_IPV4:
LE_INFO(“PDP IPv4”);
break;
case LE_MDC_PDP_IPV6:
LE_INFO(“IPDP Pv6”);
break;
case LE_MDC_PDP_IPV4V6:
LE_INFO(“PDP IPv4v6”);
break;
default:
LE_ERROR(“PDP unsupported %d”, ProfilePDP);
break;
}
//set APN
rs = le_mdc_SetAPN(modemProfile,&APN[0]);
LE_FATAL_IF(rs != LE_OK, “Couldn`t set APN.”);
rs = le_mdc_GetAPN(modemProfile, &data[0], sizeof(data));
if(LE_OK == rs)
LE_INFO(“APN: %s, %d”,data, rs);

LE_INFO("Try to Start Session.");
if (LE_OK == le_mdc_StartSession (modemProfile))
    LE_INFO("Modem is connecting.");

return LE_OK;

}

static void DataConnectionStateHandler(le_mdc_ProfileRef_t profileRef, le_mdc_ConState_t ConnectionState, void contextPtr)
{ /

LE_MDC_DISCONNECTED Data session is disconnected.
LE_MDC_AUTHENTICATING Authenticating data session.
LE_MDC_CONNECTED Data session is connected.
LE_MDC_SUSPENDING Suspending data session.
LE_MDC_INCOMING Incoming data session (MT-PDP context request)
*/
le_mdc_ConState_t state = LE_MDC_DISCONNECTED;
// Check the state
LE_ASSERT( le_mdc_GetSessionState(modemProfile, &state) == LE_OK );
if(ConnectionState != state)
LE_INFO(“State for modem doesn`t match”);

switch (ConnectionState)
{   
    case LE_MDC_DISCONNECTED:
        LE_INFO("Modem Disconnected.");
        LE_INFO("System will try to reconnect");
        //ConnectModem();
        break;
    case LE_MDC_AUTHENTICATING:
        LE_INFO("Modem Authenticating");
        break;
    case LE_MDC_CONNECTED:
        LE_INFO("Modem Just Connected");
        LE_INFO("Go to sleep for a few seconds..");
        sleep(3);
        LE_INFO("Waking up..");
        LE_INFO("Setup NETWORK configuration.");
        SetNetworkConfiguration(modemProfile);
        break;
    case LE_MDC_SUSPENDING:
        LE_INFO("Modem Suspending");
        break;
    case LE_MDC_INCOMING:
        LE_INFO("Modem Incoming");
        break;

    default:
        LE_ERROR("Unsupported MDC session state %d", ConnectionState);
        break;
}

}

COMPONENT_INIT
{
LE_INFO(“Checking modem configuration.”);
modemProfile = le_mdc_GetProfile(modemProfileIndex);
le_mdc_ConState_t modemState = LE_MDC_DISCONNECTED;

char data[200];
//Check if modem is already connected
LE_INFO("Create Handler for Connection State.");
le_mdc_SessionStateHandlerRef_t SessionStateHandler = le_mdc_AddSessionStateHandler(modemProfile, DataConnectionStateHandler, NULL);
LE_FATAL_IF(SessionStateHandler == NULL, "Session state handler not created!!");

//Connect modem
LE_ASSERT( le_mdc_GetSessionState(modemProfile, &modemState) == LE_OK );
if(modemState != LE_MDC_CONNECTED)
{
    LE_INFO("Will start connecting the modem");
    rs = ConnectModem(modemProfileIndex);
}

rs =  le_info_GetImei(&data[0], sizeof(data));
LE_INFO("IMEI: %s, %d",data, rs);
//now try to connect the router
return;

}

And the program fails at line:
LE_ASSERT( state == LE_MDC_CONNECTED );
However, the function only gets called by the handler “DataConnectionStateHandler” once the state of the modem is LE_MDC_CONNECTED, so I am a bit confused about why this is happening…
Anybody able to help about this problem?

Did post the same topic on the Legato form but the answer was that this MDC API works on WP76 and I really need to get it to work for the FX30S as well, the problem I see is if the CELL network was to drop out and then not being able to reconnect unless of a power cycle…

Hi @claudio.baldini,

Can you please help to attach your code to here again under a attached file? I will try to run that code on my FX30S device and try to investigate what is happening.

Thanks,

This is the zip for the app I am testing, it should test the operation of the modem.
App was downloaded from the legato git repository, I have only changed:
-thread_sleep with sleep
-hardcoded the APN I am using, telstra for Australian cell network
testModem.zip (205.4 KB)

I have flashed the original firmware for the FX30S, then if I run this app, it will always say that the network is unreachable.
But if I start the modem manually from shell “cm data connect”, I can ping the www.google.com.au, and the “cm data” will also print the same DNS information as those ones shown in the logs of the mdcTest app.

I believe this has been fixed, I have just removed the communication control from the handling function and it seems the modem connection is now working.