Exemple #1
0
void  requestSendUSSD(void *data, size_t datalen, RIL_Token t)
{
	ATResponse *p_response = NULL;
	int err = 0;
	char* ussdRequest;
	char* cmd;

	at_send_command("AT+CSCS=\"GSM\"", NULL);
	ussdStatus = 1;

	ussdRequest = (char*)(data);
	asprintf(&cmd, "AT+CUSD=1,%s,15", ussdRequest);
	err = at_send_command(cmd, &p_response);
	free(cmd);


	if (err < 0 || p_response->success == 0) {
		goto error;
	}
	
    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
    at_response_free(p_response);
    return;
	
error:
    at_response_free(p_response);
	RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);

}
Exemple #2
0
static void init()
{
	at_send_command("AT+CEQREQ=1,4,64,384,64,384", NULL);
	at_send_command("AT+CEQMIN=1,4,64,384,64,384", NULL);        
	at_send_command("AT+CGEQREQ=1,4,64,384,64,384", NULL);
	at_send_command("AT+CGEQMIN=1,4,64,384,64,384", NULL);

	switchToChannel(1,0);
}
Exemple #3
0
static void init()
{
    need_network_fix = 1;
	at_send_command("AT+CEQREQ=", NULL);
	at_send_command("AT+CEQMIN=", NULL);        
	at_send_command("AT+CGEQREQ=", NULL);
	at_send_command("AT+CGEQMIN=", NULL);

	switchToChannel(1,0);
}
/* Subscribe to SIM State Reporting.
 *   Enable SIM state reporting on the format *ESIMSR: <sim_state>
 */
void setPollSIMState(void *param)
{
    static int enabled = 0;

    if (((int) param == 1) && (enabled == 0)) {
        at_send_command("AT*ESIMSR=1");
        enabled = 1;
        ALOGD("%s() Enabled SIM status reporting", __func__);
    } else if (((int) param == 0) && (enabled == 1)) {
        at_send_command("AT*ESIMSR=0");
        enabled = 0;
        ALOGD("%s() Disabled SIM status reporting", __func__);
    }
}
/**
 * Enter SIM PIN, might be PIN, PIN2, PUK, PUK2, etc.
 *
 * Data can hold pointers to one or two strings, depending on what we
 * want to enter. (PUK requires new PIN, etc.).
 *
 * FIXME: Do we need to return remaining tries left on error as well?
 *        Also applies to the rest of the requests that got the retries
 *        in later commits to ril.h.
 */
void requestEnterSimPin(void *data, size_t datalen, RIL_Token t, int request)
{
    int err = 0;
    int cme_err;
    const char **strings = (const char **) data;
    int num_retries = -1;

    if (datalen == sizeof(char *)) {
        err = at_send_command("AT+CPIN=\"%s\"", strings[0]);
    } else if (datalen == 2 * sizeof(char *)) {
        if(!strings[1]){
            err = at_send_command("AT+CPIN=\"%s\"", strings[0]);
        } else {
            err = at_send_command("AT+CPIN=\"%s\",\"%s\"", strings[0], strings[1]);
        }
    } else if (datalen == 3 * sizeof(char *)) {
            err = at_send_command("AT+CPIN=\"%s\",\"%s\"", strings[0], strings[1]);
    } else
        goto error;

    cme_err = at_get_cme_error(err);

    if (cme_err != CME_ERROR_NON_CME && err != AT_NOERROR) {
        switch (cme_err) {
        case CME_SIM_PIN_REQUIRED:
        case CME_SIM_PUK_REQUIRED:
        case CME_INCORRECT_PASSWORD:
        case CME_SIM_PIN2_REQUIRED:
        case CME_SIM_PUK2_REQUIRED:
            num_retries = getNumRetries (request);
            RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, &num_retries, sizeof(int *));
            break;
        default:
            goto error;
        }
    } else {
        /*
         * Got OK, return success and wait for *EPEV to trigger poll
         * of SIM state.
         */

        num_retries = getNumRetries (request);
        RIL_onRequestComplete(t, RIL_E_SUCCESS, &num_retries, sizeof(int *));
    }
    return;
error:
    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}
void requestChangePassword(void *data, size_t datalen, RIL_Token t,
                           char *facility, int request)
{
    int err = 0;
    char *oldPassword = NULL;
    char *newPassword = NULL;
    int num_retries = -1;

    if (datalen != 3 * sizeof(char *) || strlen(facility) != 2)
        goto error;


    oldPassword = ((char **) data)[0];
    newPassword = ((char **) data)[1];

    err = at_send_command("AT+CPWD=\"%s\",\"%s\",\"%s\"", facility,
                oldPassword, newPassword);
    if (err != AT_NOERROR)
        goto error;

    num_retries = getNumRetries(request);
    RIL_onRequestComplete(t, RIL_E_SUCCESS, &num_retries, sizeof(int *));

    return;

error:
    if (at_get_cme_error(err) == CME_INCORRECT_PASSWORD) {
        num_retries = getNumRetries(request);
        RIL_onRequestComplete(t, RIL_E_PASSWORD_INCORRECT, &num_retries, sizeof(int *));
    } else
        RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}
Exemple #7
0
void requestGSMSetBroadcastSMSConfig(void *data, size_t datalen, RIL_Token t)
{
	ATResponse *atresponse = NULL;
	int err;
	char *cmd;
	RIL_GSM_BroadcastSmsConfigInfo* configInfo = (RIL_GSM_BroadcastSmsConfigInfo*)data;

	if (!configInfo->selected)
		goto error;

	/* TODO Should this test be done or shall we just let the modem return error. */       
	if ((configInfo->toServiceId - configInfo->fromServiceId) > 10)
		goto error;

	asprintf(&cmd, "AT+CSCB=0,\"%d-%d\",\"%d-%d\"", configInfo->fromServiceId, configInfo->toServiceId, configInfo->fromCodeScheme, configInfo->toCodeScheme);

	err = at_send_command(cmd, &atresponse);

	if (err < 0 || atresponse->success == 0)
		goto error;

	RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);

finally:
	at_response_free(atresponse);
	return;

error:
	RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
	goto finally;
}
Exemple #8
0
void requestExplicitCallTransfer(void *data, size_t datalen, RIL_Token t)
{
	/* MTK proprietary start */
	int ret;
	ATResponse *p_response = NULL;

        //BEGIN mtk03923 [20120210][ALPS00114093]
        if (inDTMF) {
	    RIL_onRequestComplete(t, RIL_E_CANCELLED, NULL, 0);     // RIL_E_GENERIC_FAILURE
            return;
        }
        //END   mtk03923 [20120210][ALPS00114093]


	ret = at_send_command("AT+CHLD=4", &p_response, CC_CHANNEL_CTX);

	if (ret < 0 || p_response->success == 0)
		goto error;

	RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
	at_response_free(p_response);
	return;

error:
	RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
	at_response_free(p_response);
	/* MTK proprietary end */
}
Exemple #9
0
	/**
	 * RIL_REQUEST_SET_LOCATION_UPDATES
	 *
	 * Enables/disables network state change notifications due to changes in
	 * LAC and/or CID (basically, +CREG=2 vs. +CREG=1).  
	 *
	 * Note:  The RIL implementation should default to "updates enabled"
	 * when the screen is on and "updates disabled" when the screen is off.
	 *
	 * See also: RIL_REQUEST_SCREEN_STATE, RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED.
	 */
void requestSetLocationUpdates(void *data, size_t datalen, RIL_Token t)
{
	int enable = 0;
	int err = 0;
	char *cmd;
	ATResponse *atresponse = NULL;

	enable = ((int *) data)[0];
	assert(enable == 0 || enable == 1);

	asprintf(&cmd, "AT+CREG=%d", (enable == 0 ? 1 : 2));
	err = at_send_command(cmd, &atresponse);
	free(cmd);

	if (err < 0 || atresponse->success == 0)
		goto error;

	RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);

finally:
	at_response_free(atresponse);
	return;

error:
	RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
	goto finally;
}
Exemple #10
0
/**
 * RIL_REQUEST_SET_TTY_MODE
 *
 * Ask the modem to set the TTY mode
 */
void requestSetTtyMode(void *data, size_t datalen, RIL_Token t)
{
    int err;
    ATResponse *atresponse = NULL;
    int mode = ((int *) data)[0];

    /*
     * The modem supports one TTY mode where voice and TTY tones are
     * automatically detected. FULL (1), HCO (2) and VCO (3) are therefore
     * automatically handled by the modem TTY enabled mode (1).
     */
    err = at_send_command(mode?"AT*ETTY=1":"AT*ETTY=0", &atresponse);

    if (err < 0 || atresponse->success == 0)
        goto error;

    s_ttyMode = mode;

    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);

finally:
    at_response_free(atresponse);
    return;

error:
    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
    goto finally;
}
/**
 * RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING
 *
 * Turn on STK unsol commands.
 */
void requestStkIsRunning(void *data, size_t datalen, RIL_Token t)
{
    char *cmd;
    int err;
    ATResponse *atresponse = NULL;

    asprintf(&cmd, "AT*STKC=1,\"000000000000000000\"");
    err = at_send_command(cmd, &atresponse);
    free(cmd);

    if (err < 0 || atresponse->success == 0)
        goto error;

    /* Android 2.1 does not handle the response to this RIL command
       This is seen as an error message in the radio log:
       "[0001]< RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING exception, possible 
       invalid RIL response" */
    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);

  finally:
    at_response_free(atresponse);

    return;

  error:
    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
    goto finally;
}
void sendTime(void *p)
{
    time_t t;
    struct tm tm;
    char str[20];
    char tz[6];
    int num[4];
    int tzi;
    int i;
    (void) p;

    tzset();
    t = time(NULL);

    if (!(localtime_r(&t, &tm)))
        return;
    if (!(strftime(tz, 12, "%z", &tm)))
        return;

    for (i = 0; i < 4; i++)
        num[i] = tz[i+1] - '0';

    /* convert timezone hours to timezone quarters of hours */
    tzi = (num[0] * 10 + num[1]) * 4 + (num[2] * 10 + num[3]) / 15;
    strftime(str, 20, "%y/%m/%d,%T", &tm);
    at_send_command("at+cclk=\"%s%c%02d\"", str, tz[0], tzi);
}
/**
 * RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE
 *
 * Requests to send a terminal response to SIM for a received
 * proactive command.
 */
void requestStkSendTerminalResponse(void *data, size_t datalen,
                                    RIL_Token t)
{
    char *cmd;
    int err;
    ATResponse *atresponse = NULL;
    const char *stkResponse = (const char *) data;

    asprintf(&cmd, "AT*STKR=\"%s\"", stkResponse);
    err = at_send_command(cmd, &atresponse);
    free(cmd);

    if (err < 0 || atresponse->success == 0)
        goto error;

    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);

  finally:
    at_response_free(atresponse);

    return;

  error:
    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
    goto finally;
}
/**
 * RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE
 *
 * Requests to set the preferred network type for searching and registering
 * (CS/PS domain, RAT, and operation mode).
 */
void requestSetPreferredNetworkType(void *data, size_t datalen,
                                    RIL_Token t)
{
    (void) datalen;
    int arg = 0;
    int err = 0;
    int rat;

    rat = ((int *) data)[0];

    switch (rat) {
    case PREF_NET_TYPE_GSM_WCDMA_AUTO:
    case PREF_NET_TYPE_GSM_WCDMA:
        arg = PREF_NET_TYPE_3G;
        LOGD("[%s] network type = auto", __FUNCTION__);
        break;
    case PREF_NET_TYPE_GSM_ONLY:
        arg = PREF_NET_TYPE_2G_ONLY;
        LOGD("[%s] network type = 2g only", __FUNCTION__);
        break;
    case PREF_NET_TYPE_WCDMA:
        arg = PREF_NET_TYPE_3G_ONLY;
        LOGD("[%s] network type = 3g only", __FUNCTION__);
        break;
    default:
        LOGW("[%s] unknown network type: (%d)", __FUNCTION__, rat);
    }
    pref_net_type = arg;
    err = at_send_command("AT+CFUN=%d", arg);
    RIL_onRequestComplete(t, (err == AT_NOERROR)? RIL_E_SUCCESS : RIL_E_GENERIC_FAILURE, NULL, 0);
    return;
}
/**
 * RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL
 *
 * Manually select a specified network.
 *
 * The radio baseband/RIL implementation is expected to fall back to
 * automatic selection mode if the manually selected network should go
 * out of range in the future.
 */
void requestSetNetworkSelectionManual(void *data, size_t datalen,
                                      RIL_Token t)
{
    /*
     * AT+COPS=[<mode>[,<format>[,<oper>[,<AcT>]]]]
     *    <mode>   = 4 = Manual (<oper> field shall be present and AcT optionally) with fallback to automatic if manual fails.
     *    <format> = 2 = Numeric <oper>, the number has structure:
     *                   (country code digit 3)(country code digit 2)(country code digit 1)
     *                   (network code digit 2)(network code digit 1)
     */

    (void) datalen;
    int err = 0;
    const char *mccMnc = (const char *) data;

    /* Check inparameter. */
    if (mccMnc == NULL)
        goto error;

    /* Build and send command. */
    err = at_send_command("AT+COPS=1,2,\"%s\"", mccMnc);
    if (err != AT_NOERROR)
        goto error;

    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
    return;

error:
    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}
Exemple #16
0
void requestSwitchWaitingOrHoldingAndActive(void *data, size_t datalen, RIL_Token t)
{
	int ret;
	ATResponse *p_response = NULL;

        //BEGIN mtk03923 [20120210][ALPS00114093]
        if (inDTMF) {
	    RIL_onRequestComplete(t, RIL_E_CANCELLED, NULL, 0);     // RIL_E_GENERIC_FAILURE
            return;
        }
        //END   mtk03923 [20120210][ALPS00114093]


	ret = at_send_command("AT+CHLD=2", &p_response, CC_CHANNEL_CTX);

	if (ret < 0 || p_response->success == 0)
		goto error;

#ifdef WORKAROUND_ERRONEOUS_ANSWER
	s_expectAnswer = 1;
#endif  /* WORKAROUND_ERRONEOUS_ANSWER */

	RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
	at_response_free(p_response);
	return;

error:
	RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
	at_response_free(p_response);
}
Exemple #17
0
void requestSeparateConnection(void *data, size_t datalen, RIL_Token t)
{
	char cmd[12];
	int party = ((int *)data)[0];
	int ret;
	ATResponse *p_response = NULL;

        //BEGIN mtk03923 [20120210][ALPS00114093]
        if (inDTMF) {
	    RIL_onRequestComplete(t, RIL_E_CANCELLED, NULL, 0);     // RIL_E_GENERIC_FAILURE
            return;
        }
        //END   mtk03923 [20120210][ALPS00114093]


	// Make sure that party is in a valid range.
	// (Note: The Telephony middle layer imposes a range of 1 to 7.
	// It's sufficient for us to just make sure it's single digit.)
	if (party > 0 && party < 10) {
		sprintf(cmd, "AT+CHLD=2%d", party);
		ret = at_send_command(cmd, &p_response, CC_CHANNEL_CTX);

		if (ret < 0 || p_response->success == 0) {
			at_response_free(p_response);
			goto error;
		}

		RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
		at_response_free(p_response);
		return;
	}

error:
	RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}
Exemple #18
0
void select_tech(int t)
{
	char *cmd;
	asprintf(&cmd, "AT+COPS=0,,,%d", t);
	at_send_command(cmd,NULL);
	free(cmd);
}
/**
 * RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM
 *
 * When STK application gets RIL_UNSOL_STK_CALL_SETUP, the call actually has
 * been initialized by ME already. (We could see the call has been in the 'call
 * list') So, STK application needs to accept/reject the call according as user
 * operations.
 */
void requestStkHandleCallSetupRequestedFromSIM(void *data,
                                               size_t datalen, RIL_Token t)
{
    char *cmd;
    int err;
    int answer = 0;
    ATResponse *atresponse = NULL;

    if(((int *)data)[0] > 0 ){
        answer = 1;
    }
    asprintf(&cmd, "AT*ESHLVOCR=%d", answer);
    err = at_send_command(cmd, &atresponse);
    free(cmd);

    if (err < 0 || atresponse->success == 0)
        goto error;

    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);

  finally:
    at_response_free(atresponse);

    return;

  error:
    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
    goto finally;
}
/**
 * RIL_REQUEST_STK_SET_PROFILE
 *
 * Download the STK terminal profile as part of SIM initialization
 * procedure.
 */
void requestStkSetProfile(void *data, size_t datalen, RIL_Token t)
{
#ifdef USE_U8500_RIL
    /* Currently this request is not supported. */
    RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);

    return;
#else
    char *cmd;
    int err;
    ATResponse *atresponse = NULL;
    const char *profile = (const char *) data;

    asprintf(&cmd, "AT*STKC=0,\"%s\"", profile);
    err = at_send_command(cmd, &atresponse);
    free(cmd);

    if (err < 0 || atresponse->success == 0)
    goto error;

    RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);

  finally:
    at_response_free(atresponse);

    return;

  error:
    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
  goto finally;
#endif
}
Exemple #21
0
static void requestRadioPower(void *data, size_t datalen, RIL_Token t)
{
	int onOff;
	int err=0;
	ATResponse *p_response = NULL;

	assert (datalen >= sizeof(int *));
	onOff = ((int *)data)[0];


	if (onOff == 0 && sState != RADIO_STATE_OFF) {

		if (first_cfun == 0) {
			stop_pppd();
			wait_for_pppd_down();

			err = at_send_command("AT+CFUN=0", &p_response);
			if (err < 0) 
				goto error;
		} else {
			first_cfun = 0;		
		}
		setRadioState(RADIO_STATE_OFF);

	} else if (onOff > 0 && sState == RADIO_STATE_OFF) {
		err = at_send_command("AT+CFUN=1", &p_response);
		
		if (err < 0|| p_response->success == 0) {
			// Some stacks return an error when there is no SIM,
			// but they really turn the RF portion on
			// So, if we get an error, let's check to see if it
			// turned on anyway

			if (getRadioPower() != 1) {
				goto error;
			}
		}
		setRadioState(RADIO_STATE_SIM_NOT_READY);
	}

	at_response_free(p_response);
	RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
	return;
error:
	at_response_free(p_response);
	RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}
Exemple #22
0
void switchToChannel(int channel,int l)
{
	int clvl = getClvlValue();
	if(l >= 0) clvl = l;

	char* cmd;
	at_send_command("AT+CMUT=1",NULL);
	at_send_command("AT+CLVL=0", NULL);
	asprintf(&cmd, "AT+SPEAKER=%d",channel);
	at_send_command(cmd, NULL);
	free(cmd);

	asprintf(&cmd, "AT+CLVL=%d",clvl);
	at_send_command(cmd, NULL);
	at_send_command("AT+CMUT=0",NULL);
	free(cmd); 
}
Exemple #23
0
/**
 * RIL_REQUEST_SEND_SMS_EXPECT_MORE
 *
 * Send an SMS message. Identical to RIL_REQUEST_SEND_SMS,
 * except that more messages are expected to be sent soon. If possible,
 * keep SMS relay protocol link open (eg TS 27.005 AT+CMMS command).
 */
void requestSendSMSExpectMore(void *data, size_t datalen, RIL_Token t)
{
    /* Throw the command on the channel and ignore any errors, since we
       need to send the SMS anyway and subsequent SMSes will be sent anyway. */
    (void)at_send_command("AT+CMMS=1", NULL);

    requestSendSMS(data, datalen, t);
}
Exemple #24
0
static void deleteMessageByIndex(void* index)
{
	char* cmd = NULL;
	asprintf(&cmd, "AT+CMGD=%d",*(int*)index);
	at_send_command(cmd,NULL);
	free(cmd);
	free(index);
}
static int setCharEncoding(const char *enc){
    int err;
    err = at_send_command("AT+CSCS=\"%s\"", enc);
    if (err < 0) {
        LOGE("requestSetupDefaultPDP: Failed to set AT+CSCS=%s", enc);
        return -1;
    }
    return 0;
}
Exemple #26
0
static void readMessageByIndex(void *param)
{
	int location = (int)param;
	char *cmd;

	asprintf(&cmd, "AT+CMGR=%d,0", location);
	at_send_command(cmd, NULL);
	free(cmd);
}
Exemple #27
0
static int set_phone_book(int index, phone_book_t* pb)
{
	int ret = -1, err;
	char* cmd = NULL;
	char* line = NULL;
    ATResponse *p_response = NULL;
	asprintf(&cmd,"AT+CPBW=%d, \"%s\", %d, \"%s\"", index, pb->number, pb->code, pb->alpha);

	at_send_command("AT+CSCS=\"UCS2\"", NULL);
	err = at_send_command(cmd, &p_response);
	if (err < 0 || !p_response || p_response->success == 0)
		goto error;
	ret = 0;
error:
	at_response_free(p_response);
	free(cmd);
	return ret;	
}
Exemple #28
0
void requestUdub(void *data, size_t datalen, RIL_Token t)
{
	/* user determined user busy */
	/* sometimes used: ATH */
	at_send_command("ATH", NULL, CC_CHANNEL_CTX);

	/* success or failure is ignored by the upper layer here.
	 * it will call GET_CURRENT_CALLS and determine success that way */
	RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}
Exemple #29
0
void requestHangupWaitingOrBackground(void *data, size_t datalen, RIL_Token t)
{
	// 3GPP 22.030 6.5.5
	// "Releases all held calls or sets User Determined User Busy
	//  (UDUB) for a waiting call."
	at_send_command("AT+CHLD=0", NULL, CC_CHANNEL_CTX);

	/* success or failure is ignored by the upper layer here.
	 * it will call GET_CURRENT_CALLS and determine success that way */
	RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}
Exemple #30
0
void requestSetVoiceVolume(int *data, size_t datalen, RIL_Token t)
{
	ATResponse *p_response = NULL;
	int err;	
	char *cmd;

	asprintf(&cmd, "AT+CLVL=%d", data[0]);
	err = at_send_command(cmd, NULL);	
	free(cmd);
	RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}