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:
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 doesnt 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?