mirror of https://github.com/ARMmbed/mbed-os.git
Add support for the Telit ME310 module (LwIP/PPP and AT command-based IP stacks)
parent
d0d35c2743
commit
125f169342
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "TELIT_ME310.h"
|
||||
#include "TELIT_ME310_CellularContext.h"
|
||||
#include "TELIT_ME310_CellularStack.h"
|
||||
#include "TELIT_ME310_CellularNetwork.h"
|
||||
#include "AT_CellularNetwork.h"
|
||||
#include "PinNames.h"
|
||||
#include "rtos/ThisThread.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
using namespace mbed;
|
||||
using namespace rtos;
|
||||
using namespace events;
|
||||
|
||||
#if !defined(MBED_CONF_TELIT_ME310_PWR)
|
||||
#define MBED_CONF_TELIT_ME310_PWR NC
|
||||
#endif
|
||||
|
||||
#if !defined(MBED_CONF_TELIT_ME310_TX)
|
||||
#define MBED_CONF_TELIT_ME310_TX NC
|
||||
#endif
|
||||
|
||||
#if !defined(MBED_CONF_TELIT_ME310_RX)
|
||||
#define MBED_CONF_TELIT_ME310_RX NC
|
||||
#endif
|
||||
|
||||
#if !defined(MBED_CONF_TELIT_ME310_POLARITY)
|
||||
#define MBED_CONF_TELIT_ME310_POLARITY 1 // active high
|
||||
#endif
|
||||
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_EREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_REG
|
||||
0, // AT_CGSN_WITH_TYPE
|
||||
0, // AT_CGDATA
|
||||
1, // AT_CGAUTH
|
||||
1, // AT_CNMI
|
||||
1, // AT_CSMP
|
||||
1, // AT_CMGF
|
||||
1, // AT_CSDH
|
||||
1, // PROPERTY_IPV4_STACK
|
||||
1, // PROPERTY_IPV6_STACK
|
||||
1, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
1, // PROPERTY_AT_CGEREP,
|
||||
1, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
6, // PROPERTY_SOCKET_COUNT
|
||||
1, // PROPERTY_IP_TCP
|
||||
1, // PROPERTY_IP_UDP
|
||||
20, // PROPERTY_AT_SEND_DELAY
|
||||
};
|
||||
|
||||
TELIT_ME310::TELIT_ME310(FileHandle *fh, PinName pwr, bool active_high)
|
||||
: AT_CellularDevice(fh),
|
||||
_active_high(active_high),
|
||||
_pwr_key(pwr, !_active_high)
|
||||
{
|
||||
set_cellular_properties(cellular_properties);
|
||||
}
|
||||
|
||||
AT_CellularContext *TELIT_ME310::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req)
|
||||
{
|
||||
return new TELIT_ME310_CellularContext(at, this, apn, cp_req, nonip_req);
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310::init()
|
||||
{
|
||||
nsapi_error_t err = AT_CellularDevice::init();
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
return err;
|
||||
}
|
||||
_at.lock();
|
||||
#if defined (MBED_CONF_TELIT_ME310_RTS) && defined (MBED_CONF_TELIT_ME310_CTS)
|
||||
_at.at_cmd_discard("&K3;&C1;&D0", "");
|
||||
#else
|
||||
_at.at_cmd_discard("&K0;&C1;&D0", "");
|
||||
#endif
|
||||
|
||||
// AT#QSS=1
|
||||
// Enable the Query SIM Status unsolicited indication in the ME. The format of the
|
||||
// unsolicited indication is the following:
|
||||
// #QSS: <status>
|
||||
// The ME informs at
|
||||
// every SIM status change through the basic unsolicited indication where <status> range is 0...1
|
||||
// <status> values:
|
||||
// - 0: SIM not inserted
|
||||
// - 1: SIM inserted
|
||||
_at.at_cmd_discard("#QSS", "=1");
|
||||
|
||||
// AT#PSNT=1
|
||||
// Set command enables unsolicited result code for packet service network type (PSNT)
|
||||
// having the following format:
|
||||
// #PSNT:<nt>
|
||||
// <nt> values:
|
||||
// - 0: GPRS network
|
||||
// - 4: LTE network
|
||||
// - 5: unknown or not registered
|
||||
_at.at_cmd_discard("#PSNT", "=1");
|
||||
|
||||
// AT+CMER=2
|
||||
// Set command enables sending of unsolicited result codes from TA to TE in the case of
|
||||
// indicator state changes.
|
||||
// Current setting: buffer +CIEV Unsolicited Result Codes in the TA when TA-TE link is
|
||||
// reserved (e.g. on-line data mode) and flush them to the TE after
|
||||
// reservation; otherwise forward them directly to the TE
|
||||
_at.at_cmd_discard("+CMER", "=2");
|
||||
|
||||
// AT+CMEE=2
|
||||
// Set command disables the use of result code +CME ERROR: <err> as an indication of an
|
||||
// error relating to the +Cxxx command issued. When enabled, device related errors cause the +CME
|
||||
// ERROR: <err> final result code instead of the default ERROR final result code. ERROR is returned
|
||||
// normally when the error message is related to syntax, invalid parameters or DTE functionality.
|
||||
// Current setting: enable and use verbose <err> values
|
||||
_at.at_cmd_discard("+CMEE", "=2");
|
||||
|
||||
// AT&W&P
|
||||
// - AT&W: Execution command stores on profile <n> the complete configuration of the device. If
|
||||
// parameter is omitted, the command has the same behavior of AT&W0.
|
||||
// - AT&P: Execution command defines which full profile will be loaded at startup. If parameter
|
||||
// is omitted, the command has the same behavior as AT&P0
|
||||
_at.at_cmd_discard("&W&P", "");
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
#if MBED_CONF_TELIT_ME310_PROVIDE_DEFAULT
|
||||
#include "drivers/BufferedSerial.h"
|
||||
CellularDevice *CellularDevice::get_default_instance()
|
||||
{
|
||||
static BufferedSerial serial(MBED_CONF_TELIT_ME310_TX, MBED_CONF_TELIT_ME310_RX, MBED_CONF_TELIT_ME310_BAUDRATE);
|
||||
#if defined (MBED_CONF_TELIT_ME310_RTS) && defined (MBED_CONF_TELIT_ME310_CTS)
|
||||
serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_TELIT_ME310_RTS, MBED_CONF_TELIT_ME310_CTS);
|
||||
#endif
|
||||
static TELIT_ME310 device(&serial,
|
||||
MBED_CONF_TELIT_ME310_PWR,
|
||||
MBED_CONF_TELIT_ME310_POLARITY);
|
||||
return &device;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsapi_error_t TELIT_ME310::hard_power_on()
|
||||
{
|
||||
soft_power_on();
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310::soft_power_on()
|
||||
{
|
||||
_pwr_key = _active_high;
|
||||
ThisThread::sleep_for(500ms);
|
||||
_pwr_key = !_active_high;
|
||||
ThisThread::sleep_for(5s);
|
||||
_pwr_key = _active_high;
|
||||
ThisThread::sleep_for(5s);
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310::hard_power_off()
|
||||
{
|
||||
_pwr_key = !_active_high;
|
||||
ThisThread::sleep_for(10s);
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310::soft_power_off()
|
||||
{
|
||||
return AT_CellularDevice::soft_power_off();
|
||||
}
|
||||
|
||||
AT_CellularNetwork *TELIT_ME310::open_network_impl(ATHandler &at)
|
||||
{
|
||||
return new TELIT_ME310_CellularNetwork(at, *this);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef CELLULAR_TARGETS_TELIT_ME310_TELIT_ME310_H_
|
||||
#define CELLULAR_TARGETS_TELIT_ME310_TELIT_ME310_H_
|
||||
|
||||
#ifdef TARGET_FF_ARDUINO
|
||||
#ifndef MBED_CONF_TELIT_ME310_TX
|
||||
#define MBED_CONF_TELIT_ME310_TX D1
|
||||
#endif
|
||||
#ifndef MBED_CONF_TELIT_ME310_RX
|
||||
#define MBED_CONF_TELIT_ME310_RX D0
|
||||
#endif
|
||||
#endif /* TARGET_FF_ARDUINO */
|
||||
|
||||
#include "DigitalOut.h"
|
||||
#include "AT_CellularDevice.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class TELIT_ME310 : public AT_CellularDevice {
|
||||
public:
|
||||
/**
|
||||
* Constructs the Telit ME310 series driver. It is mandatory to provide
|
||||
* a FileHandle object, the power pin and the polarity of the pin.
|
||||
*/
|
||||
TELIT_ME310(FileHandle *fh, PinName pwr, bool active_high);
|
||||
|
||||
protected: // AT_CellularDevice
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn, bool cp_req = false, bool nonip_req = false);
|
||||
virtual nsapi_error_t init();
|
||||
virtual nsapi_error_t hard_power_on();
|
||||
virtual nsapi_error_t hard_power_off();
|
||||
virtual nsapi_error_t soft_power_on();
|
||||
virtual nsapi_error_t soft_power_off();
|
||||
virtual AT_CellularNetwork *open_network_impl(ATHandler &at);
|
||||
|
||||
private:
|
||||
bool _active_high;
|
||||
DigitalOut _pwr_key;
|
||||
};
|
||||
} // namespace mbed
|
||||
#endif /* CELLULAR_TARGETS_TELIT_ME310_TELIT_ME310_H_ */
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "TELIT_ME310_CellularContext.h"
|
||||
#include "TELIT_ME310_CellularStack.h"
|
||||
#include "CellularLog.h"
|
||||
|
||||
#include "Semaphore.h"
|
||||
|
||||
using namespace mbed_cellular_util;
|
||||
|
||||
namespace mbed {
|
||||
|
||||
TELIT_ME310_CellularContext::TELIT_ME310_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) :
|
||||
AT_CellularContext(at, device, apn, cp_req, nonip_req)
|
||||
{
|
||||
}
|
||||
|
||||
TELIT_ME310_CellularContext::~TELIT_ME310_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
NetworkStack *TELIT_ME310_CellularContext::get_stack()
|
||||
{
|
||||
if (_pdp_type == NON_IP_PDP_TYPE || (_nonip_req && _pdp_type != DEFAULT_PDP_TYPE)) {
|
||||
tr_error("Requesting stack for NON-IP context! Should request control plane netif: get_cp_netif()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_stack) {
|
||||
_stack = new TELIT_ME310_CellularStack(_at, _cid, (nsapi_ip_stack_t)_pdp_type, *get_device());
|
||||
}
|
||||
|
||||
return _stack;
|
||||
}
|
||||
#endif // #if !NSAPI_PPP_AVAILABLE
|
||||
|
||||
bool TELIT_ME310_CellularContext::get_context()
|
||||
{
|
||||
bool modem_supports_ipv6 = get_device()->get_property(AT_CellularDevice::PROPERTY_IPV6_PDP_TYPE);
|
||||
bool modem_supports_ipv4 = get_device()->get_property(AT_CellularDevice::PROPERTY_IPV4_PDP_TYPE);
|
||||
|
||||
_at.cmd_start_stop("+CGDCONT", "?");
|
||||
_at.resp_start("+CGDCONT:");
|
||||
_cid = -1;
|
||||
int cid_max = 0; // needed when creating new context
|
||||
char apn[MAX_ACCESSPOINT_NAME_LENGTH];
|
||||
int apn_len = 0;
|
||||
|
||||
while (_at.info_resp()) {
|
||||
int cid = _at.read_int();
|
||||
if (cid > cid_max) {
|
||||
cid_max = cid;
|
||||
}
|
||||
char pdp_type_from_context[10];
|
||||
int pdp_type_len = _at.read_string(pdp_type_from_context, sizeof(pdp_type_from_context));
|
||||
if (pdp_type_len > 0) {
|
||||
apn_len = _at.read_string(apn, sizeof(apn));
|
||||
if (apn_len >= 0) {
|
||||
if (_apn && apn_len > 0 && (strcmp(apn, _apn) != 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// APN matched -> Check PDP type
|
||||
pdp_type_t pdp_type = string_to_pdp_type(pdp_type_from_context);
|
||||
|
||||
// Accept exact matching PDP context type or dual PDP context for IPv4/IPv6 only modems
|
||||
if (get_device()->get_property(pdp_type_t_to_cellular_property(pdp_type)) ||
|
||||
((pdp_type == IPV4V6_PDP_TYPE && (modem_supports_ipv4 || modem_supports_ipv6)) && !_nonip_req)) {
|
||||
_pdp_type = pdp_type;
|
||||
set_new_context(cid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_at.resp_stop();
|
||||
if (_cid == -1) { // no suitable context was found so create a new one
|
||||
if (!set_new_context(1)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// save the apn
|
||||
if (apn_len > 0 && !_apn) {
|
||||
memcpy(_found_apn, apn, apn_len + 1);
|
||||
}
|
||||
|
||||
tr_info("Found PDP context %d", _cid);
|
||||
return true;
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef TELIT_ME310_CELLULARCONTEXT_H_
|
||||
#define TELIT_ME310_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class TELIT_ME310_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
TELIT_ME310_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req = false, bool nonip_req = false);
|
||||
virtual ~TELIT_ME310_CellularContext();
|
||||
protected:
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
virtual NetworkStack *get_stack();
|
||||
#endif // #if !NSAPI_PPP_AVAILABLE
|
||||
virtual bool get_context();
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // TELIT_ME310_CELLULARCONTEXT_H_
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "TELIT_ME310_CellularNetwork.h"
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
TELIT_ME310_CellularNetwork::TELIT_ME310_CellularNetwork(ATHandler &atHandler, AT_CellularDevice &device) : AT_CellularNetwork(atHandler, device)
|
||||
{
|
||||
}
|
||||
|
||||
TELIT_ME310_CellularNetwork::~TELIT_ME310_CellularNetwork()
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310_CellularNetwork::set_access_technology_impl(RadioAccessTechnology opsAct)
|
||||
{
|
||||
switch (opsAct) {
|
||||
case RAT_GSM:
|
||||
case RAT_CATM1:
|
||||
case RAT_NB1:
|
||||
_op_act = opsAct;
|
||||
return NSAPI_ERROR_OK;
|
||||
|
||||
default:
|
||||
_op_act = RAT_UNKNOWN;
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2019, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TELIT_ME310_CELLULAR_NETWORK_H_
|
||||
#define TELIT_ME310_CELLULAR_NETWORK_H_
|
||||
|
||||
#include "AT_CellularNetwork.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class TELIT_ME310_CellularNetwork : public AT_CellularNetwork {
|
||||
public:
|
||||
TELIT_ME310_CellularNetwork(ATHandler &atHandler, AT_CellularDevice &device);
|
||||
virtual ~ TELIT_ME310_CellularNetwork();
|
||||
|
||||
protected:
|
||||
virtual nsapi_error_t set_access_technology_impl(RadioAccessTechnology opRat);
|
||||
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // TELIT_ME310_CELLULAR_NETWORK_H_
|
|
@ -0,0 +1,646 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "TELIT_ME310_CellularStack.h"
|
||||
#include "CellularLog.h"
|
||||
#include "netsocket/TLSSocket.h"
|
||||
|
||||
static const int sslctxID = 1;
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
TELIT_ME310_CellularStack::TELIT_ME310_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device) :
|
||||
AT_CellularStack(atHandler, cid, stack_type, device)
|
||||
, _tls_sec_level(0)
|
||||
{
|
||||
|
||||
_at.set_urc_handler("SRING:", mbed::Callback<void()>(this, &TELIT_ME310_CellularStack::urc_sring));
|
||||
|
||||
// TODO: this needs to be handled properly, but now making just a quick hack
|
||||
// Close all SSL sockets if open. This can happen for example if application processor
|
||||
// was reset but modem not. Old sockets are still up and running and it prevents
|
||||
// new SSL configurations and creating new sockets.
|
||||
for (int i = 1; i <= ME310_SOCKET_MAX; i++) {
|
||||
_at.clear_error();
|
||||
tr_debug("Closing SSL socket %d...", i);
|
||||
_at.at_cmd_discard("#SSLH", "=", "%d", "0", i);
|
||||
}
|
||||
_at.clear_error();
|
||||
}
|
||||
|
||||
TELIT_ME310_CellularStack::~TELIT_ME310_CellularStack()
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310_CellularStack::socket_listen(nsapi_socket_t handle, int backlog)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310_CellularStack::socket_accept(void *server, void **socket, SocketAddress *addr)
|
||||
{
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
|
||||
{
|
||||
CellularSocket *socket = (CellularSocket *)handle;
|
||||
|
||||
if (!is_ipeasy_context_activated(_cid)) {
|
||||
activate_ipeasy_context(_cid);
|
||||
}
|
||||
|
||||
int modem_connect_id = -1;
|
||||
int err = NSAPI_ERROR_NO_CONNECTION;
|
||||
|
||||
int request_connect_id = find_socket_index(socket);
|
||||
// assert here as its a programming error if the socket container doesn't contain
|
||||
// specified handle
|
||||
MBED_ASSERT(request_connect_id != -1);
|
||||
|
||||
_at.lock();
|
||||
|
||||
// Configure SRING URC
|
||||
_at.at_cmd_discard("#SCFGEXT", "=", "%d%d%d%d",
|
||||
request_connect_id + 1,
|
||||
1, // SRING URC mode - data amount mode
|
||||
0, // Data view mode - text mode
|
||||
0); // TCP keepalive - deactivated
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
tr_warn("Unable to configure socket %d", request_connect_id);
|
||||
}
|
||||
|
||||
if (socket->proto == NSAPI_TCP) {
|
||||
if (socket->tls_socket) {
|
||||
if (_tls_sec_level == 0) {
|
||||
_at.unlock();
|
||||
return NSAPI_ERROR_AUTH_FAILURE;
|
||||
}
|
||||
|
||||
_at.at_cmd_discard("#SSLD", "=", "%d%d%s%d", sslctxID,
|
||||
address.get_port(),
|
||||
address.get_ip_address(),
|
||||
0); // Closure type (0)
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
// Hit some sort of error opening the socket
|
||||
socket->id = -1;
|
||||
_at.unlock();
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
} else {
|
||||
_at.at_cmd_discard("#SD", "=", "%d%d%d%s%d%d%d", request_connect_id + 1, 0, address.get_port(), address.get_ip_address(), 0,
|
||||
0, 1);
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
// Hit some sort of error opening the socket
|
||||
socket->id = -1;
|
||||
_at.unlock();
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t ret_val = _at.get_last_error();
|
||||
_at.unlock();
|
||||
|
||||
if (ret_val == NSAPI_ERROR_OK) {
|
||||
socket->id = request_connect_id;
|
||||
socket->remoteAddress = address;
|
||||
socket->connected = true;
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void TELIT_ME310_CellularStack::urc_sring()
|
||||
{
|
||||
_at.lock();
|
||||
const int sock_id = _at.read_int() - 1;
|
||||
const int data_bytes_remaining = _at.read_int();
|
||||
const nsapi_error_t err = _at.unlock_return_error();
|
||||
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
CellularSocket *sock = find_socket(sock_id);
|
||||
if (sock) {
|
||||
sock->pending_bytes = data_bytes_remaining;
|
||||
if (sock->_cb) {
|
||||
sock->_cb(sock->_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int TELIT_ME310_CellularStack::get_max_socket_count()
|
||||
{
|
||||
return ME310_SOCKET_MAX;
|
||||
}
|
||||
|
||||
bool TELIT_ME310_CellularStack::is_protocol_supported(nsapi_protocol_t protocol)
|
||||
{
|
||||
return (protocol == NSAPI_UDP || protocol == NSAPI_TCP);
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310_CellularStack::socket_close_impl(int sock_id)
|
||||
{
|
||||
_at.set_at_timeout(ME310_CLOSE_SOCKET_TIMEOUT);
|
||||
nsapi_error_t err;
|
||||
CellularSocket *socket = find_socket(sock_id);
|
||||
if (socket && socket->tls_socket) {
|
||||
err = _at.at_cmd_discard("#SSLH", "=", "%d%d", sock_id, 0);
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
// Disable TLSSocket settings to prevent reuse on next socket without setting the values
|
||||
_tls_sec_level = 0;
|
||||
err = _at.at_cmd_discard("#SSLEN", "=,", "%d%d", sslctxID, 0);
|
||||
}
|
||||
} else {
|
||||
err = _at.at_cmd_discard("#SH", "=", "%d", sock_id + 1);
|
||||
}
|
||||
_at.restore_at_timeout();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
bool TELIT_ME310_CellularStack::is_ipeasy_context_activated(int context_id)
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
_at.cmd_start_stop("#SGACT?", "");
|
||||
_at.resp_start("#SGACT:");
|
||||
|
||||
int current_context_id = -1;
|
||||
int current_stat = -1;
|
||||
|
||||
for (int i = 0; i < ME310_CONTEXT_MAX; i++) {
|
||||
current_context_id = _at.read_int();
|
||||
current_stat = _at.read_int();
|
||||
|
||||
if (current_context_id == context_id) {
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
return current_stat == ME310_IPEASY_ACTIVATED_CONTEXT;
|
||||
}
|
||||
}
|
||||
|
||||
_at.resp_stop();
|
||||
_at.unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310_CellularStack::activate_ipeasy_context(int context_id)
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
_at.at_cmd_discard("#SGACT", "=", "%d%d", context_id, ME310_IPEASY_ACTIVATED_CONTEXT);
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310_CellularStack::deactivate_ipeasy_context(int context_id)
|
||||
{
|
||||
_at.lock();
|
||||
|
||||
_at.at_cmd_discard("#SGACT", "=", "%d%d", context_id, ME310_IPEASY_DEACTIVATED_CONTEXT);
|
||||
|
||||
return _at.unlock_return_error();
|
||||
}
|
||||
|
||||
nsapi_error_t TELIT_ME310_CellularStack::create_socket_impl(CellularSocket *socket)
|
||||
{
|
||||
int modem_connect_id = -1;
|
||||
int remote_port = 1;
|
||||
int err = -1;
|
||||
|
||||
if (!is_ipeasy_context_activated(_cid)) {
|
||||
tr_debug("IPEasy context not active for %d", _cid);
|
||||
activate_ipeasy_context(_cid);
|
||||
}
|
||||
|
||||
int request_connect_id = find_socket_index(socket);
|
||||
// assert here as its a programming error if the socket container doesn't contain
|
||||
// specified handle
|
||||
MBED_ASSERT(request_connect_id != -1);
|
||||
|
||||
// Configure SRING URC
|
||||
_at.at_cmd_discard("#SCFGEXT", "=", "%d%d%d%d",
|
||||
request_connect_id + 1,
|
||||
1, // SRING URC mode - data amount mode
|
||||
0, // Data view mode - text mode
|
||||
0); // TCP keepalive - deactivated
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
tr_warn("Unable to configure socket %d", request_connect_id);
|
||||
}
|
||||
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
_at.at_cmd_discard("#SD", "=", "%d%d%d%s%d%d%d", request_connect_id + 1, 1, remote_port,
|
||||
(_ip_ver_sendto == NSAPI_IPv4) ? "127.0.0.1" : "0:0:0:0:0:0:0:1",
|
||||
0, socket->localAddress.get_port(), 1);
|
||||
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
// Hit some sort of error opening the socket
|
||||
socket->id = -1;
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
} else if (socket->proto == NSAPI_TCP) {
|
||||
_at.at_cmd_discard("#SD", "=", "%d%d%d%s%d%d%d%d", request_connect_id + 1, 0, remote_port,
|
||||
socket->remoteAddress.get_ip_address(), 0, 0, 1);
|
||||
|
||||
if (_at.get_last_error() != NSAPI_ERROR_OK) {
|
||||
// Hit some sort of error opening the socket
|
||||
socket->id = -1;
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
}
|
||||
nsapi_error_t ret_val = _at.get_last_error();
|
||||
|
||||
if (ret_val == NSAPI_ERROR_OK) {
|
||||
socket->id = request_connect_id;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t TELIT_ME310_CellularStack::socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
|
||||
const void *data, nsapi_size_t size)
|
||||
{
|
||||
tr_debug("TELIT_ME310_CellularStack::socket_sendto_impl()");
|
||||
|
||||
int sent_len = 0;
|
||||
bool success = true;
|
||||
const char *buf = (const char *) data;
|
||||
nsapi_size_t blk = ME310_MAX_SEND_SIZE;
|
||||
nsapi_size_t count = size;
|
||||
int sent_len_before = 0;
|
||||
int sent_len_after = 0;
|
||||
|
||||
while ((count > 0) && success) {
|
||||
if (count < blk) {
|
||||
blk = count;
|
||||
}
|
||||
|
||||
if (socket->tls_socket) {
|
||||
sent_len_after = blk;
|
||||
} else {
|
||||
// Get the sent count before sending
|
||||
_at.cmd_start_stop("#SI", "=", "%d", socket->id + 1);
|
||||
_at.resp_start("#SI:");
|
||||
_at.skip_param();
|
||||
sent_len_before = _at.read_int();
|
||||
_at.resp_stop();
|
||||
}
|
||||
|
||||
// Send
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
_at.cmd_start_stop("#SSENDUDPEXT", "=", "%d%d%s%d", socket->id + 1, size,
|
||||
address.get_ip_address(), address.get_port());
|
||||
} else {
|
||||
if (socket->tls_socket) {
|
||||
_at.cmd_start_stop("#SSLSENDEXT", "=", "%d%d", socket->id + 1, size);
|
||||
} else {
|
||||
_at.cmd_start_stop("#SSENDEXT", "=", "%d%d", socket->id + 1, size);
|
||||
}
|
||||
}
|
||||
|
||||
_at.resp_start("> ", true);
|
||||
_at.write_bytes((uint8_t *)buf, blk);
|
||||
|
||||
_at.cmd_start(CTRL_Z);
|
||||
_at.cmd_stop();
|
||||
_at.resp_start("\r\nOK", true);
|
||||
_at.resp_stop();
|
||||
|
||||
if (!socket->tls_socket) {
|
||||
_at.cmd_start_stop("#SI", "=", "%d", socket->id + 1);
|
||||
_at.resp_start("#SI:");
|
||||
_at.skip_param();
|
||||
sent_len_after = _at.read_int();
|
||||
_at.resp_stop();
|
||||
}
|
||||
|
||||
sent_len = sent_len_after - sent_len_before;
|
||||
|
||||
if ((sent_len >= (int) blk) &&
|
||||
(_at.get_last_error() == NSAPI_ERROR_OK)) {
|
||||
} else {
|
||||
success = false;
|
||||
}
|
||||
|
||||
buf += blk;
|
||||
count -= blk;
|
||||
}
|
||||
|
||||
if (success && _at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
return size - count;
|
||||
}
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t TELIT_ME310_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size)
|
||||
{
|
||||
tr_debug("TELIT_ME310_CellularStack::socket_recvfrom_impl()");
|
||||
|
||||
nsapi_size_or_error_t nsapi_error_size = NSAPI_ERROR_DEVICE_ERROR;
|
||||
bool success = true;
|
||||
nsapi_size_t read_blk;
|
||||
nsapi_size_t count = 0;
|
||||
nsapi_size_t srecv_size;
|
||||
Timer timer;
|
||||
int port = -1;
|
||||
char ip_address[NSAPI_IP_SIZE + 1];
|
||||
|
||||
if (socket->pending_bytes == 0) {
|
||||
_at.process_oob(); // check for SRING URC
|
||||
if (socket->pending_bytes == 0) {
|
||||
tr_debug("Socket %d recv would block", socket->id);
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
timer.start();
|
||||
while (success && (size > 0)) {
|
||||
read_blk = ME310_MAX_RECV_SIZE;
|
||||
if (read_blk > size) {
|
||||
read_blk = size;
|
||||
}
|
||||
if (socket->pending_bytes > 0) {
|
||||
if (socket->proto == NSAPI_TCP) {
|
||||
if (socket->tls_socket) {
|
||||
_at.cmd_start_stop("#SSLRECV", "=", "%d%d", socket->id + 1, read_blk);
|
||||
} else {
|
||||
_at.cmd_start_stop("#SRECV", "=", "%d%d", socket->id + 1, read_blk);
|
||||
}
|
||||
} else {
|
||||
_at.cmd_start_stop("#SRECV", "=", "%d%d%d", socket->id + 1, read_blk, 1);
|
||||
}
|
||||
|
||||
if (socket->tls_socket) {
|
||||
_at.resp_start("#SSLRECV:");
|
||||
} else {
|
||||
_at.resp_start("#SRECV:");
|
||||
}
|
||||
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
int data_left = -1;
|
||||
// UDP has remote_IP and remote_port parameters
|
||||
_at.read_string(ip_address, sizeof(ip_address));
|
||||
port = _at.read_int();
|
||||
|
||||
// Skip connId
|
||||
_at.skip_param();
|
||||
|
||||
srecv_size = _at.read_int();
|
||||
data_left = _at.read_int();
|
||||
if (srecv_size > size) {
|
||||
srecv_size = size;
|
||||
}
|
||||
|
||||
_at.read_bytes((uint8_t *)buffer + count, srecv_size);
|
||||
} else {
|
||||
// Skip connId
|
||||
_at.skip_param();
|
||||
|
||||
srecv_size = _at.read_int();
|
||||
if (srecv_size > size) {
|
||||
srecv_size = size;
|
||||
}
|
||||
|
||||
_at.read_bytes((uint8_t *)buffer + count, srecv_size);
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
if (srecv_size > socket->pending_bytes) {
|
||||
socket->pending_bytes = 0;
|
||||
} else {
|
||||
socket->pending_bytes -= srecv_size;
|
||||
}
|
||||
|
||||
if (srecv_size > 0) {
|
||||
count += srecv_size;
|
||||
size -= srecv_size;
|
||||
} else {
|
||||
// read() should not fail
|
||||
success = false;
|
||||
}
|
||||
} else if (timer.read_ms() < ME310_SOCKET_TIMEOUT) {
|
||||
// Wait for URCs
|
||||
_at.process_oob();
|
||||
} else {
|
||||
if (count == 0) {
|
||||
// Timeout with nothing received
|
||||
success = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
timer.stop();
|
||||
|
||||
if (!count || (_at.get_last_error() != NSAPI_ERROR_OK)) {
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
} else {
|
||||
nsapi_error_size = count;
|
||||
}
|
||||
|
||||
if (success && address) {
|
||||
address->set_ip_address(ip_address);
|
||||
address->set_port(port);
|
||||
}
|
||||
|
||||
return nsapi_error_size;
|
||||
}
|
||||
|
||||
#if defined(MBED_CONF_NSAPI_OFFLOAD_TLSSOCKET) && (MBED_CONF_NSAPI_OFFLOAD_TLSSOCKET)
|
||||
|
||||
nsapi_error_t TELIT_ME310_CellularStack::setsockopt(nsapi_socket_t handle, int level,
|
||||
int optname, const void *optval, unsigned optlen)
|
||||
{
|
||||
CellularSocket *socket = (CellularSocket *)handle;
|
||||
nsapi_error_t ret = NSAPI_ERROR_OK;
|
||||
int ssl_enabled = 0;
|
||||
uint8_t ctrl_z[] = { 0x1A };
|
||||
|
||||
if (level == NSAPI_TLSSOCKET_LEVEL) {
|
||||
if (optval) {
|
||||
_at.lock();
|
||||
switch (optname) {
|
||||
case NSAPI_TLSSOCKET_ENABLE: {
|
||||
MBED_ASSERT(optlen == sizeof(bool));
|
||||
bool *enabled = (bool *)optval;
|
||||
if (socket->proto == NSAPI_TCP) {
|
||||
socket->tls_socket = enabled;
|
||||
|
||||
if (enabled) {
|
||||
_at.at_cmd_discard("#SSLEN", "=", "%d%d", sslctxID, 1);
|
||||
_at.at_cmd_discard("#SSLSECCFG", "=", "%d%d%d", sslctxID, 0, _tls_sec_level);
|
||||
_at.at_cmd_discard("#SSLCFG", "=", "%d%d%d%d%d%d",
|
||||
sslctxID,
|
||||
_cid, // PDP context ID
|
||||
0, // Packet size (0 is default, select automatically)
|
||||
90, // Max socket inactivity time (90 is default)
|
||||
100, // Default timeout when no timeout is set (100 is default)
|
||||
50); // Transmit timeout (50 is default)
|
||||
|
||||
ret = _at.get_last_error();
|
||||
}
|
||||
} else {
|
||||
tr_error("Trying to set non-TCPSocket as TLSSocket");
|
||||
ret = NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NSAPI_TLSSOCKET_SET_CACERT: {
|
||||
_at.cmd_start_stop("#SSLEN", "?");
|
||||
_at.resp_start("#SSLEN:");
|
||||
|
||||
// Skip SSId
|
||||
_at.skip_param();
|
||||
|
||||
ssl_enabled = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
if (ssl_enabled == 0) {
|
||||
// SSL not enabled, so enable it
|
||||
_at.at_cmd_discard("#SSLEN", "=", "%d%d", sslctxID, 1);
|
||||
}
|
||||
|
||||
_at.flush();
|
||||
|
||||
const char *cacert = (const char *)optval;
|
||||
int cacert_size = strlen(cacert);
|
||||
_at.cmd_start_stop("#SSLSECDATA", "=", "%d%d%d%d", sslctxID,
|
||||
1, // store data
|
||||
1, // CA cert
|
||||
cacert_size);
|
||||
_at.resp_start("> ", true);
|
||||
_at.write_bytes((uint8_t *)cacert, cacert_size);
|
||||
|
||||
_at.write_bytes(ctrl_z, 1); // Send Ctrl+Z
|
||||
|
||||
_at.resp_start("\r\nOK", true);
|
||||
_at.resp_stop();
|
||||
|
||||
ret = _at.get_last_error();
|
||||
|
||||
// Set sec level to "Manage server authentication" if only cacert is in use
|
||||
if (ret == NSAPI_ERROR_OK && _tls_sec_level == 0) {
|
||||
_tls_sec_level = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NSAPI_TLSSOCKET_SET_CLCERT: {
|
||||
_at.cmd_start_stop("#SSLEN", "?");
|
||||
_at.resp_start("#SSLEN:");
|
||||
|
||||
// Skip SSId
|
||||
_at.skip_param();
|
||||
|
||||
ssl_enabled = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
if (ssl_enabled == 0) {
|
||||
// SSL not enabled, so enable it
|
||||
_at.at_cmd_discard("#SSLEN", "=", "%d%d", sslctxID, 1);
|
||||
}
|
||||
|
||||
_at.flush();
|
||||
|
||||
const char *clcert = (const char *)optval;
|
||||
int clcert_size = strlen(clcert);
|
||||
_at.cmd_start_stop("#SSLSECDATA", "=", "%d%d%d%d", sslctxID,
|
||||
1, // store data
|
||||
0, // client cert
|
||||
clcert_size);
|
||||
_at.resp_start("> ", true);
|
||||
_at.write_bytes((uint8_t *)clcert, clcert_size);
|
||||
|
||||
_at.write_bytes(ctrl_z, 1); // Send Ctrl+Z
|
||||
|
||||
_at.resp_start("\r\nOK", true);
|
||||
_at.resp_stop();
|
||||
|
||||
ret = _at.get_last_error();
|
||||
|
||||
// Set sec level to "Manage server and client authentication if requested by the remote server"
|
||||
if (ret == NSAPI_ERROR_OK) {
|
||||
_tls_sec_level = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NSAPI_TLSSOCKET_SET_CLKEY: {
|
||||
_at.cmd_start_stop("#SSLEN", "?");
|
||||
_at.resp_start("#SSLEN:");
|
||||
|
||||
// Skip SSId
|
||||
_at.skip_param();
|
||||
|
||||
ssl_enabled = _at.read_int();
|
||||
_at.resp_stop();
|
||||
|
||||
if (ssl_enabled == 0) {
|
||||
// SSL not enabled, so enable it
|
||||
_at.at_cmd_discard("#SSLEN", "=", "%d%d", sslctxID, 1);
|
||||
}
|
||||
|
||||
_at.flush();
|
||||
|
||||
const char *clkey = (const char *)optval;
|
||||
int clkey_size = strlen(clkey);
|
||||
_at.cmd_start_stop("#SSLSECDATA", "=", "%d%d%d%d", sslctxID,
|
||||
1, // store data
|
||||
2, // client key
|
||||
clkey_size);
|
||||
_at.resp_start("> ", true);
|
||||
_at.write_bytes((uint8_t *)clkey, clkey_size);
|
||||
|
||||
_at.write_bytes(ctrl_z, 1); // Send Ctrl+Z
|
||||
|
||||
_at.resp_start("\r\nOK", true);
|
||||
_at.resp_stop();
|
||||
|
||||
ret = _at.get_last_error();
|
||||
|
||||
// Set sec level to "Manage server and client authentication if requested by the remote server"
|
||||
if (ret == NSAPI_ERROR_OK) {
|
||||
_tls_sec_level = 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
tr_error("Unsupported sockopt (%d)", optname);
|
||||
ret = NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
_at.unlock();
|
||||
} else {
|
||||
tr_error("No optval!");
|
||||
ret = NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
} else {
|
||||
tr_warning("Unsupported level (%d)", level);
|
||||
ret = NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2020, Arm Limited and affiliates.
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef TELIT_ME310_CELLULARSTACK_H_
|
||||
#define TELIT_ME310_CELLULARSTACK_H_
|
||||
|
||||
#include "AT_CellularStack.h"
|
||||
#include "mbed_trace.h"
|
||||
#include "drivers/Timer.h"
|
||||
|
||||
|
||||
namespace mbed {
|
||||
|
||||
#define ME310_SOCKET_MAX 6
|
||||
#define ME310_CONTEXT_MAX 6
|
||||
#define ME310_CREATE_SOCKET_TIMEOUT 150000 //150 seconds
|
||||
#define ME310_CLOSE_SOCKET_TIMEOUT 20000 // TCP socket max timeout is >10sec
|
||||
#define ME310_MAX_RECV_SIZE 1000
|
||||
#define ME310_MAX_SEND_SIZE 1023
|
||||
#define ME310_SOCKET_BIND_FAIL 556
|
||||
#define ME310_IPEASY_ACTIVATED_CONTEXT 1
|
||||
#define ME310_IPEASY_DEACTIVATED_CONTEXT 0
|
||||
#define ME310_SOCKET_TIMEOUT 1000
|
||||
#define CTRL_Z "\x1a"
|
||||
#define ESC "\x1b"
|
||||
|
||||
class TELIT_ME310_CellularStack : public AT_CellularStack {
|
||||
public:
|
||||
TELIT_ME310_CellularStack(ATHandler &atHandler, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device);
|
||||
virtual ~TELIT_ME310_CellularStack();
|
||||
|
||||
protected: // NetworkStack
|
||||
|
||||
virtual nsapi_error_t socket_listen(nsapi_socket_t handle, int backlog);
|
||||
|
||||
virtual nsapi_error_t socket_accept(nsapi_socket_t server,
|
||||
nsapi_socket_t *handle, SocketAddress *address = 0);
|
||||
|
||||
virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address);
|
||||
|
||||
#if defined(MBED_CONF_NSAPI_OFFLOAD_TLSSOCKET) && (MBED_CONF_NSAPI_OFFLOAD_TLSSOCKET)
|
||||
virtual nsapi_error_t setsockopt(nsapi_socket_t handle, int level,
|
||||
int optname, const void *optval, unsigned optlen);
|
||||
#endif
|
||||
|
||||
protected: // AT_CellularStack
|
||||
|
||||
virtual int get_max_socket_count();
|
||||
|
||||
virtual bool is_protocol_supported(nsapi_protocol_t protocol);
|
||||
|
||||
virtual nsapi_error_t socket_close_impl(int sock_id);
|
||||
|
||||
virtual nsapi_error_t create_socket_impl(CellularSocket *socket);
|
||||
|
||||
virtual nsapi_size_or_error_t socket_sendto_impl(CellularSocket *socket, const SocketAddress &address,
|
||||
const void *data, nsapi_size_t size);
|
||||
|
||||
virtual nsapi_size_or_error_t socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size);
|
||||
|
||||
private:
|
||||
// URC handler for socket data being received
|
||||
void urc_sring();
|
||||
|
||||
bool is_ipeasy_context_activated(int context_id);
|
||||
nsapi_error_t activate_ipeasy_context(int context_id);
|
||||
nsapi_error_t deactivate_ipeasy_context(int context_id);
|
||||
|
||||
uint8_t _tls_sec_level;
|
||||
};
|
||||
} // namespace mbed
|
||||
#endif /* TELIT_ME310_CELLULARSTACK_H_ */
|
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"name": "TELIT_ME310",
|
||||
"config": {
|
||||
"tx": {
|
||||
"help": "TX pin for serial connection. D1 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.",
|
||||
"value": null
|
||||
},
|
||||
"rx": {
|
||||
"help": "RX pin for serial connection. D0 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.",
|
||||
"value": null
|
||||
},
|
||||
"rts": {
|
||||
"help": "RTS pin for serial connection",
|
||||
"value": null
|
||||
},
|
||||
"cts": {
|
||||
"help": "CTS pin for serial connection",
|
||||
"value": null
|
||||
},
|
||||
"pwr": {
|
||||
"help": "Power control pin",
|
||||
"value": null
|
||||
},
|
||||
"polarity": {
|
||||
"help": "Pin polarity, 1 = Active high, 0 = Active low",
|
||||
"value": null
|
||||
},
|
||||
"baudrate" : {
|
||||
"help": "Serial connection baud rate",
|
||||
"value": 115200
|
||||
},
|
||||
"provide-default": {
|
||||
"help": "Provide as default CellularDevice [true/false]",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue