blob: 6bb906a5ed6805a358b13e6c69cd4978b310a3a0 [file] [log] [blame]
/******************************************************************************
*(C) Copyright 2014 Marvell International Ltd.
* All Rights Reserved
******************************************************************************/
/* -------------------------------------------------------------------------------------------------------------------
*
* Filename: main.c
*
* Authors: Adrian Zelezniak
*
* Description: Entry Point of the MBIM Translator
*
* HISTORY:
*
* Jan 7, 2014 - Initial Version
*
* Notes:
*
******************************************************************************/
/******************************************************************************
* Include files
******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <signal.h>
#include <assert.h>
#define LOG_TAG "MBIM"
#include "mbim_types.h"
#include "mbim_util.h"
#include "mbim_protocol.h"
#if defined MBIM_MTIL
#include "mbim_mtil.h"
#include "mbim_pcap.h"
#include "mbim_cm.h"
#include "eeh_assert_notify.h"
#else
#include "mbim_ril.h"
#endif
/******************************************************************************
* Macros
******************************************************************************/
//#define USE_MTIL_INIT_THREAD 1
/******************************************************************************
* External variables
******************************************************************************/
unsigned int board_ip = 0;
extern MBIM_DATABASE mbimDb;
/******************************************************************************
* Function prototypes
******************************************************************************/
static void handleArg(int argc, char *argv[]);
static void printUsage(char *progName);
/******************************************************************************
* Code
******************************************************************************/
#if defined MBIM_MTIL
extern int property_get(const char *name, const char* value, const char* default_value);
#endif
static void MbimDumpBuffer (char *buff, int len)
{
int i;
char *bufstr;
MBIM_LOGE("%s: buffer len = %d", __FUNCTION__, len);
bufstr = malloc(len*3+3);
bufstr[0] = '\0';
for (i = 0 ; i < len ; i++)
{
sprintf(bufstr, " %02X", buff[i]);
}
MBIM_LOGE("%s: buff = %s", __FUNCTION__, bufstr);
free(bufstr);
}
void MbimReadFromDevice(int fd)
{
int dataLen;
int index = 0;
//Read from MBIM driver
if ( (dataLen = read(fd, mbimDb.inBuf, mbimDb.maxControlTransfer)) < 0 )
{
MBIM_LOGE("Error while reading from MBIM device return\n");
return;
}
MBIM_LOGD("%s: read %d bytes to socket %d", __FUNCTION__, dataLen, fd);
if (dataLen == 0)
{
MBIM_LOGD("Read Zero\n");
return;
}
do
{
P_MBIM_MESSAGE_HEADER mbimHdr_p = (P_MBIM_MESSAGE_HEADER)&mbimDb.inBuf[index];
int msgLength = mbimHdr_p->messageLength;
MBIM_LOGD("%s: MbimProcessEncapCommand, ptr = %p, len = %d", __FUNCTION__, &mbimDb.inBuf[index], mbimHdr_p->messageLength);
if (msgLength == 0)
{
MbimDumpBuffer(&mbimDb.inBuf[index], dataLen);
break;
}
//Parse the received command (Need to later see whatt to do with fragmentation!!!)
if ( MbimProcessEncapCommand(&mbimDb.inBuf[index], msgLength) < MBIM_OK )
{
MBIM_LOGE("Command message Error");
}
dataLen -= msgLength;
index += msgLength;
MBIM_LOGD("%s: MbimProcessEncapCommand done, dataLen = %d, index = %d", __FUNCTION__, dataLen, index);
}while(dataLen > 0);
//reset received buffer
memset(mbimDb.inBuf, 0, mbimDb.maxControlTransfer);
}
static void *MbimMainLoopTask (void *arg)
{
int dataLen, ret;
int sock_fd;
sock_fd = mbimDb.pipes_fd[1];
MBIM_LOGE("%s: MbimSocketClient returned socket fd = %d", __FUNCTION__, sock_fd);
while (TRUE)
{
//Read from MBIM driver
if ( (dataLen = read(mbimDb.mbimDeviceHandler, mbimDb.inBufFromDrv, mbimDb.maxControlTransferFromDrv)) < 0 )
{
MBIM_LOGE("Error while reading from MBIM device return\n");
sleep(2);
continue;
}
if (dataLen == 0)
{
MBIM_LOGD("Read Zero\n");
sleep(2);
continue;
}
MBIM_LOGD("%s: write %d bytes from %08X to socket %d", __FUNCTION__, dataLen, mbimDb.inBufFromDrv, sock_fd);
ret = write(sock_fd, mbimDb.inBufFromDrv, dataLen);
MBIM_LOGD("%s: wrote %d bytes to socket %d", __FUNCTION__, ret, sock_fd);
MbimHandleCommand (mbimDb.inBufFromDrv, dataLen);
//reset received buffer
memset(mbimDb.inBufFromDrv, 0, mbimDb.maxControlTransferFromDrv);
};
return arg;
}
static void sighandler(int signo)
{
MBIM_LOGD("Received signal %d\n", signo);
assert(0);
return;
}
static inline void sighandler_setup(void)
{
MBIM_LOGD("setup sighandler\n");
signal(SIGABRT, sighandler);
signal(SIGFPE, sighandler);
signal(SIGILL, sighandler);
signal(SIGINT, sighandler);
signal(SIGSEGV, sighandler);
signal(SIGTERM, sighandler);
}
/*******************************************************************************\
* Function: main
\*******************************************************************************/
int main(int argc, char *argv[])
{
int rc = MBIM_OK;
#if defined (MBIM_MTIL)
int dataLen;
char prop [255]; //Added for testing LTE configuration in 3G NW (Will open 3 pdp's as VZN)
#endif
#ifdef USE_MTIL_INIT_THREAD
pthread_t tid = 0;
#endif
mbim_disableAutoDial();
/*
* ToDo - find alternative
*
* eeh_init_signal_handling("mbim", (SIG_TO_MASK(SIGALRM) | SIG_TO_MASK(SIGCHLD)), 0);
*/
mbimDb.debug_enable = 1; //make sure we print version info
/*LOGCAT showing with ACAT Tool */
set_service_log_tag(LOG_TAG);
MBIM_LOGD("Vesion 3.0");
//memset(&mbimDb, 0, sizeof(mbimDb));
//sighandler_setup();
//Handle the received Arguments
handleArg(argc, argv);
//Init all the MBIM parameters
MbimInit();
#if defined (MBIM_MTIL)
//Register MTIL Client (Phase I --> In Phase II need to move to Open and close command)
if (MtilClient_Init(client_name) < 0) {
MBIM_LOGE("Failed MTIL ClientAPI Initializing.\n");
exit(1);
} else
MBIM_LOGD("MTIL ClientAPI Initialized.\n");
#else
if (MbimTelInit("MBIM") != 0) {
MBIM_LOGE("Failed MbimTelInit Initializing.\n");
exit(1);
} else {
MBIM_LOGD("MbimTelInit Initialized.\n");
}
#endif
//Bind to Kernel
if (MbimKernelBind() < MBIM_OK) {
MBIM_LOGE("Failed Kernel Bind Initializing.\n");
exit(1);
} else
MBIM_LOGD("Kernel Bind Initialized.\n");
#if defined (MBIM_MTIL)
//check if we are in test mode for (3G VZN)
property_get(MBIM_VZN_APN_RULE_PROPERTY, (const char *)prop, "replace");
if (strcmp(prop, MBIM_VZN_APN_RULE_3G_VZN_TEST) == 0)
{
//Send Simulated PLMN Indication
simulatePlmnInfoInd();
}
/*
* The following property listener will
* wait for activation and deactivation
* pcac logging
*/
PropertiesListenerInit();
#endif
#if defined (MBIM_USE_RIL)
if (pipe(mbimDb.pipes_fd) != 0)
{
int err = errno;
char *errstr = strerror(err);
MBIM_LOGE("%s: pipe failed with error %d [ %s ].", __FUNCTION__, err, errstr);
return -1;
}
pthread_create(&mbimDb.tid, NULL, MbimMainLoopTask, NULL);
MbimTelMainLoop(mbimDb.pipes_fd[0]);
#else
//MBIM main loop
while (TRUE)
{
//Read from MBIM driver
if ( (dataLen = read(mbimDb.mbimDeviceHandler, mbimDb.inBuf, mbimDb.maxControlTransfer)) < 0 )
{
MBIM_LOGE("Error while reading from MBIM device return\n");
rc = MBIM_BIND_READ_ERROR;
break;
}
if (dataLen == 0)
{
MBIM_LOGD("Read Zero\n");
sleep(2);
continue;
}
/* pcap log */
PCAP_CMD_WRITE(mbimDb.inBuf,dataLen);
//Parse the received command (Need to later see whatt to do with fragmentation!!!)
if ( MbimProcessEncapCommand(mbimDb.inBuf,dataLen) < MBIM_OK )
{
MBIM_LOGE("Command message Error");
}
//reset received buffer
memset(mbimDb.inBuf, 0, sizeof(mbimDb.inBuf));
};
#endif
#if defined (MBIM_MTIL)
//Close MTIL Client
MtilClient_Deinit();
#else
MbimTelDeinit();
#endif
return rc;
}
/*******************************************************************************\
* Function: printUsage
\*******************************************************************************/
static void printUsage(char *progName)
{
#if defined MBIM_MTIL
MBIM_LOGI("%s -- MTIL AT Command Server. Call with MtilATcmd [inputs [output]]\n", progName);
#endif
MBIM_LOGI("CopyRight (c) 2014 Marvell Israel\n");
MBIM_LOGI("Usage: %s [-h]\n", progName);
//// NEED to complete the USAGE explanation ////
}
/*******************************************************************************\
* Function: handleArg
\*******************************************************************************/
static void handleArg(int argc, char *argv[])
{
int i;
char *cp, opt;
for (i = 1; i < argc; i++)
{
cp = argv[i];
if (*cp == '-' || *cp == '/')
{
opt = *(++cp);
switch (opt)
{
case 'h':
printUsage(argv[0]);
exit(0);
break;
case 'i':
if ((i + 1) < argc) {
i++;
board_ip = (unsigned long)inet_addr(argv[i]);
}
break;
case 'd':
mbimDb.debug_enable = 1;
break;
default:
{
;
}
break;
}
}
}
}