Import Mbed OS hard-float snapshot
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* 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 "GEMALTO_CINTERION_CellularContext.h"
|
||||
#include "GEMALTO_CINTERION_CellularInformation.h"
|
||||
#include "GEMALTO_CINTERION.h"
|
||||
#include "AT_CellularNetwork.h"
|
||||
#include "CellularLog.h"
|
||||
|
||||
using namespace mbed;
|
||||
using namespace events;
|
||||
|
||||
GEMALTO_CINTERION::Module GEMALTO_CINTERION::_module;
|
||||
|
||||
GEMALTO_CINTERION::GEMALTO_CINTERION(FileHandle *fh) : AT_CellularDevice(fh)
|
||||
{
|
||||
}
|
||||
|
||||
AT_CellularContext *GEMALTO_CINTERION::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req)
|
||||
{
|
||||
return new GEMALTO_CINTERION_CellularContext(at, this, apn, cp_req, nonip_req);
|
||||
}
|
||||
|
||||
AT_CellularInformation *GEMALTO_CINTERION::open_information_impl(ATHandler &at)
|
||||
{
|
||||
if (_module == ModuleBGS2) {
|
||||
return new GEMALTO_CINTERION_CellularInformation(at, *this);
|
||||
}
|
||||
return AT_CellularDevice::open_information_impl(at);
|
||||
}
|
||||
|
||||
nsapi_error_t GEMALTO_CINTERION::init()
|
||||
{
|
||||
nsapi_error_t err = AT_CellularDevice::init();
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
CellularInformation *information = open_information();
|
||||
if (!information) {
|
||||
return NSAPI_ERROR_NO_MEMORY;
|
||||
}
|
||||
char model[sizeof("EHS5-E") + 1]; // sizeof need to be long enough to hold just the model text
|
||||
nsapi_error_t ret = information->get_model(model, sizeof(model));
|
||||
close_information();
|
||||
if (ret != NSAPI_ERROR_OK) {
|
||||
tr_error("Cellular model not found!");
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
if (memcmp(model, "ELS61", sizeof("ELS61") - 1) == 0) {
|
||||
init_module_els61();
|
||||
} else if (memcmp(model, "BGS2", sizeof("BGS2") - 1) == 0) {
|
||||
init_module_bgs2();
|
||||
} else if (memcmp(model, "EMS31", sizeof("EMS31") - 1) == 0) {
|
||||
init_module_ems31();
|
||||
} else if (memcmp(model, "EHS5-E", sizeof("EHS5-E") - 1) == 0) {
|
||||
init_module_ehs5e();
|
||||
} else {
|
||||
tr_error("Cinterion model unsupported %s", model);
|
||||
return NSAPI_ERROR_UNSUPPORTED;
|
||||
}
|
||||
tr_info("Cinterion model %s (%d)", model, _module);
|
||||
|
||||
set_at_urcs();
|
||||
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
GEMALTO_CINTERION::Module GEMALTO_CINTERION::get_module()
|
||||
{
|
||||
return _module;
|
||||
}
|
||||
|
||||
void GEMALTO_CINTERION::init_module_bgs2()
|
||||
{
|
||||
// BGS2-W_ATC_V00.100
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
AT_CellularNetwork::RegistrationModeDisable, // C_EREG
|
||||
AT_CellularNetwork::RegistrationModeEnable, // C_GREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_REG
|
||||
0, // AT_CGSN_WITH_TYPE
|
||||
1, // AT_CGDATA
|
||||
1, // AT_CGAUTH
|
||||
1, // AT_CNMI
|
||||
1, // AT_CSMP
|
||||
1, // AT_CMGF
|
||||
1, // AT_CSDH
|
||||
1, // PROPERTY_IPV4_STACK
|
||||
0, // PROPERTY_IPV6_STACK
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
1, // PROPERTY_AT_CGEREP
|
||||
1, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
10, // PROPERTY_SOCKET_COUNT
|
||||
1, // PROPERTY_IP_TCP
|
||||
1, // PROPERTY_IP_UDP
|
||||
100,// PROPERTY_AT_SEND_DELAY, if baud is below 9600 this must be longer
|
||||
};
|
||||
set_cellular_properties(cellular_properties);
|
||||
_module = ModuleBGS2;
|
||||
}
|
||||
|
||||
void GEMALTO_CINTERION::init_module_els61()
|
||||
{
|
||||
// ELS61-E2_ATC_V01.000
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
AT_CellularNetwork::RegistrationModeDisable, // C_EREG
|
||||
AT_CellularNetwork::RegistrationModeEnable, // C_GREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_REG
|
||||
0, // AT_CGSN_WITH_TYPE
|
||||
1, // 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
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
1, // PROPERTY_AT_CGEREP
|
||||
1, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
10, // PROPERTY_SOCKET_COUNT
|
||||
1, // PROPERTY_IP_TCP
|
||||
1, // PROPERTY_IP_UDP
|
||||
100,// PROPERTY_AT_SEND_DELAY, if baud is below 9600 this must be longer
|
||||
};
|
||||
set_cellular_properties(cellular_properties);
|
||||
_module = ModuleELS61;
|
||||
}
|
||||
|
||||
void GEMALTO_CINTERION::init_module_ems31()
|
||||
{
|
||||
// EMS31-US_ATC_V4.9.5
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_EREG
|
||||
AT_CellularNetwork::RegistrationModeDisable, // C_GREG
|
||||
AT_CellularNetwork::RegistrationModeDisable, // C_REG
|
||||
1, // AT_CGSN_WITH_TYPE
|
||||
1, // 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
|
||||
10, // PROPERTY_SOCKET_COUNT
|
||||
1, // PROPERTY_IP_TCP
|
||||
1, // PROPERTY_IP_UDP
|
||||
100,// PROPERTY_AT_SEND_DELAY, if baud is below 9600 this must be longer
|
||||
};
|
||||
set_cellular_properties(cellular_properties);
|
||||
_module = ModuleEMS31;
|
||||
}
|
||||
|
||||
void GEMALTO_CINTERION::init_module_ehs5e()
|
||||
{
|
||||
// EHS5-E
|
||||
static const intptr_t cellular_properties[AT_CellularDevice::PROPERTY_MAX] = {
|
||||
AT_CellularNetwork::RegistrationModeDisable, // C_EREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
|
||||
AT_CellularNetwork::RegistrationModeLAC, // C_REG
|
||||
0, // AT_CGSN_WITH_TYPE
|
||||
1, // 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
|
||||
0, // PROPERTY_IPV4V6_STACK
|
||||
0, // PROPERTY_NON_IP_PDP_TYPE
|
||||
1, // PROPERTY_AT_CGEREP
|
||||
1, // PROPERTY_AT_COPS_FALLBACK_AUTO
|
||||
10, // PROPERTY_SOCKET_COUNT
|
||||
1, // PROPERTY_IP_TCP
|
||||
1, // PROPERTY_IP_UDP
|
||||
100,// PROPERTY_AT_SEND_DELAY, if baud is below 9600 this must be longer
|
||||
};
|
||||
set_cellular_properties(cellular_properties);
|
||||
_module = ModuleEHS5E;
|
||||
}
|
||||
|
||||
#if MBED_CONF_GEMALTO_CINTERION_PROVIDE_DEFAULT
|
||||
#include "drivers/BufferedSerial.h"
|
||||
CellularDevice *CellularDevice::get_default_instance()
|
||||
{
|
||||
static BufferedSerial serial(MBED_CONF_GEMALTO_CINTERION_TX, MBED_CONF_GEMALTO_CINTERION_RX, MBED_CONF_GEMALTO_CINTERION_BAUDRATE);
|
||||
#if defined(MBED_CONF_GEMALTO_CINTERION_RTS) && defined(MBED_CONF_GEMALTO_CINTERION_CTS)
|
||||
tr_debug("GEMALTO_CINTERION flow control: RTS %d CTS %d", MBED_CONF_GEMALTO_CINTERION_RTS, MBED_CONF_GEMALTO_CINTERION_CTS);
|
||||
serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_GEMALTO_CINTERION_RTS, MBED_CONF_GEMALTO_CINTERION_CTS);
|
||||
#endif
|
||||
static GEMALTO_CINTERION device(&serial);
|
||||
return &device;
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef GEMALTO_CINTERION_H_
|
||||
#define GEMALTO_CINTERION_H_
|
||||
|
||||
#ifdef TARGET_FF_ARDUINO
|
||||
#ifndef MBED_CONF_GEMALTO_CINTERION_TX
|
||||
#define MBED_CONF_GEMALTO_CINTERION_TX D1
|
||||
#endif
|
||||
#ifndef MBED_CONF_GEMALTO_CINTERION_RX
|
||||
#define MBED_CONF_GEMALTO_CINTERION_RX D0
|
||||
#endif
|
||||
#endif /* TARGET_FF_ARDUINO */
|
||||
|
||||
#include "AT_CellularDevice.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class GEMALTO_CINTERION : public AT_CellularDevice {
|
||||
public:
|
||||
GEMALTO_CINTERION(FileHandle *fh);
|
||||
|
||||
/** Actual model of cellular module is needed to make AT command adaptation at runtime
|
||||
* to support many different models in one cellular driver.
|
||||
*/
|
||||
enum Module {
|
||||
ModuleUnknown = 0,
|
||||
ModuleELS61,
|
||||
ModuleBGS2,
|
||||
ModuleEMS31,
|
||||
ModuleEHS5E,
|
||||
};
|
||||
static Module get_module();
|
||||
|
||||
protected: // AT_CellularDevice
|
||||
virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn, bool cp_req = false, bool nonip_req = false);
|
||||
virtual AT_CellularInformation *open_information_impl(ATHandler &at);
|
||||
|
||||
protected:
|
||||
virtual nsapi_error_t init();
|
||||
|
||||
private:
|
||||
static Module _module;
|
||||
void init_module_bgs2();
|
||||
void init_module_els61();
|
||||
void init_module_ems31();
|
||||
void init_module_ehs5e();
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // GEMALTO_CINTERION_H_
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 "GEMALTO_CINTERION_CellularContext.h"
|
||||
#include "GEMALTO_CINTERION_CellularStack.h"
|
||||
#include "CellularLog.h"
|
||||
#include "CellularDevice.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
GEMALTO_CINTERION_CellularContext::GEMALTO_CINTERION_CellularContext(ATHandler &at, CellularDevice *device,
|
||||
const char *apn, bool cp_req, bool nonip_req) : AT_CellularContext(at, device, apn, cp_req, nonip_req)
|
||||
{
|
||||
}
|
||||
|
||||
GEMALTO_CINTERION_CellularContext::~GEMALTO_CINTERION_CellularContext()
|
||||
{
|
||||
}
|
||||
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
NetworkStack *GEMALTO_CINTERION_CellularContext::get_stack()
|
||||
{
|
||||
if (_pdp_type == NON_IP_PDP_TYPE || _cp_in_use) {
|
||||
tr_error("Requesting stack for NON-IP context! Should request control plane netif: get_cp_netif()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_stack) {
|
||||
_stack = new GEMALTO_CINTERION_CellularStack(_at, _apn, _uname, _pwd, _cid, (nsapi_ip_stack_t)_pdp_type, *get_device());
|
||||
if (static_cast<GEMALTO_CINTERION_CellularStack *>(_stack)->socket_stack_init() != NSAPI_ERROR_OK) {
|
||||
delete _stack;
|
||||
_stack = NULL;
|
||||
}
|
||||
}
|
||||
return _stack;
|
||||
}
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
|
||||
} /* namespace mbed */
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef GEMALTO_CINTERION_CELLULARCONTEXT_H_
|
||||
#define GEMALTO_CINTERION_CELLULARCONTEXT_H_
|
||||
|
||||
#include "AT_CellularContext.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class GEMALTO_CINTERION_CellularContext: public AT_CellularContext {
|
||||
public:
|
||||
GEMALTO_CINTERION_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req = false, bool nonip_req = false);
|
||||
virtual ~GEMALTO_CINTERION_CellularContext();
|
||||
|
||||
protected:
|
||||
#if !NSAPI_PPP_AVAILABLE
|
||||
virtual NetworkStack *get_stack();
|
||||
#endif // NSAPI_PPP_AVAILABLE
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif // GEMALTO_CINTERION_CELLULARCONTEXT_H_
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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 "GEMALTO_CINTERION_CellularInformation.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
GEMALTO_CINTERION_CellularInformation::GEMALTO_CINTERION_CellularInformation(ATHandler &at, AT_CellularDevice &device) : AT_CellularInformation(at, device)
|
||||
{
|
||||
}
|
||||
|
||||
nsapi_error_t GEMALTO_CINTERION_CellularInformation::get_iccid(char *buf, size_t buf_size)
|
||||
{
|
||||
return _at.at_cmd_str("^SCID", "", buf, buf_size);
|
||||
}
|
||||
|
||||
} /* namespace mbed */
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef GEMALTO_CINTERION_CELLULARINFORMATION_H_
|
||||
#define GEMALTO_CINTERION_CELLULARINFORMATION_H_
|
||||
|
||||
#include "AT_CellularInformation.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class GEMALTO_CINTERION_CellularInformation: public AT_CellularInformation {
|
||||
public:
|
||||
GEMALTO_CINTERION_CellularInformation(ATHandler &at, AT_CellularDevice &device);
|
||||
|
||||
public: // AT_CellularInformation
|
||||
virtual nsapi_error_t get_iccid(char *buf, size_t buf_size);
|
||||
};
|
||||
|
||||
} /* namespace mbed */
|
||||
|
||||
#endif /* GEMALTO_CINTERION_CELLULARINFORMATION_H_ */
|
||||
@@ -0,0 +1,584 @@
|
||||
/*
|
||||
* 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 <cstdlib>
|
||||
#include "GEMALTO_CINTERION_CellularStack.h"
|
||||
#include "GEMALTO_CINTERION.h"
|
||||
#include "CellularLog.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
// defines as per ELS61-E2_ATC_V01.000 and BGS2-W_ATC_V00.100
|
||||
#define UDP_PACKET_SIZE 1460
|
||||
#define FAILURE_TIMEOUT 30s // failure timeout on modem side
|
||||
|
||||
using namespace mbed;
|
||||
|
||||
GEMALTO_CINTERION_CellularStack::GEMALTO_CINTERION_CellularStack(ATHandler &atHandler, const char *apn, const char *user, const char *password,
|
||||
int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device) :
|
||||
AT_CellularStack(atHandler, cid, stack_type, device), _apn(apn), _user(user), _password(password)
|
||||
{
|
||||
}
|
||||
|
||||
GEMALTO_CINTERION_CellularStack::~GEMALTO_CINTERION_CellularStack()
|
||||
{
|
||||
_at.set_urc_handler("^SIS:", nullptr);
|
||||
_at.set_urc_handler("^SISW:", nullptr);
|
||||
_at.set_urc_handler("^SISR:", nullptr);
|
||||
}
|
||||
|
||||
void GEMALTO_CINTERION_CellularStack::urc_sis()
|
||||
{
|
||||
int sock_id = _at.read_int();
|
||||
int urc_code = _at.read_int();
|
||||
CellularSocket *sock = find_socket(sock_id);
|
||||
if (sock) {
|
||||
// Currently only UDP is supported so there is need to handle only some error codes here,
|
||||
// and others are detected on sendto/recvfrom responses.
|
||||
if (urc_code == 5) { // The service is ready to use (ELS61 and EMS31).
|
||||
if (sock->_cb) {
|
||||
sock->started = true;
|
||||
sock->tx_ready = true;
|
||||
sock->_cb(sock->_data);
|
||||
}
|
||||
}
|
||||
if (urc_code == 0) {
|
||||
int urc_info_id = _at.read_int();
|
||||
if (urc_info_id == 48) {
|
||||
tr_info("Socket closed %d", sock_id);
|
||||
sock->closed = true;
|
||||
if (sock->_cb) {
|
||||
sock->_cb(sock->_data);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GEMALTO_CINTERION_CellularStack::urc_sisw()
|
||||
{
|
||||
int sock_id = _at.read_int();
|
||||
int urc_code = _at.read_int();
|
||||
sisw_urc_handler(sock_id, urc_code);
|
||||
}
|
||||
|
||||
void GEMALTO_CINTERION_CellularStack::sisw_urc_handler(int sock_id, int urc_code)
|
||||
{
|
||||
CellularSocket *sock = find_socket(sock_id);
|
||||
if (sock) {
|
||||
if (urc_code == 1) { // ready
|
||||
if (sock->_cb) {
|
||||
sock->tx_ready = true;
|
||||
if (sock->proto == NSAPI_TCP || GEMALTO_CINTERION::get_module() == GEMALTO_CINTERION::ModuleBGS2) {
|
||||
sock->started = true;
|
||||
}
|
||||
sock->_cb(sock->_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GEMALTO_CINTERION_CellularStack::urc_sisr()
|
||||
{
|
||||
int sock_id = _at.read_int();
|
||||
int urc_code = _at.read_int();
|
||||
sisr_urc_handler(sock_id, urc_code);
|
||||
}
|
||||
|
||||
void GEMALTO_CINTERION_CellularStack::sisr_urc_handler(int sock_id, int urc_code)
|
||||
{
|
||||
CellularSocket *sock = find_socket(sock_id);
|
||||
if (sock) {
|
||||
if (urc_code == 1) { // data available
|
||||
if (sock->_cb) {
|
||||
sock->pending_bytes = 1;
|
||||
sock->_cb(sock->_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_stack_init()
|
||||
{
|
||||
_at.lock();
|
||||
nsapi_error_t err = create_connection_profile(_cid);
|
||||
if (!err) {
|
||||
_at.set_urc_handler("^SIS:", mbed::Callback<void()>(this, &GEMALTO_CINTERION_CellularStack::urc_sis));
|
||||
_at.set_urc_handler("^SISW:", mbed::Callback<void()>(this, &GEMALTO_CINTERION_CellularStack::urc_sisw));
|
||||
_at.set_urc_handler("^SISR:", mbed::Callback<void()>(this, &GEMALTO_CINTERION_CellularStack::urc_sisr));
|
||||
} else { // recovery cleanup
|
||||
// close all Internet and connection profiles
|
||||
for (int i = 0; i < _device.get_property(AT_CellularDevice::PROPERTY_SOCKET_COUNT); i++) {
|
||||
_at.clear_error();
|
||||
socket_close_impl(i);
|
||||
}
|
||||
_at.clear_error();
|
||||
close_connection_profile(_cid);
|
||||
}
|
||||
_at.unlock();
|
||||
return err;
|
||||
}
|
||||
|
||||
nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_close_impl(int sock_id)
|
||||
{
|
||||
tr_debug("Cinterion close %d", sock_id);
|
||||
|
||||
_at.set_at_timeout(FAILURE_TIMEOUT);
|
||||
|
||||
_at.at_cmd_discard("^SISC", "=", "%d", sock_id);
|
||||
|
||||
_at.clear_error(); // clear SISS even though SISC fails
|
||||
|
||||
_at.at_cmd_discard("^SISS", "=", "%d%s%s", sock_id, "srvType", "none");
|
||||
|
||||
_at.restore_at_timeout();
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_open_defer(CellularSocket *socket, const SocketAddress *address)
|
||||
{
|
||||
int retry_open = 1;
|
||||
retry_open:
|
||||
// setup internet session profile
|
||||
int internet_service_id = find_socket_index(socket);
|
||||
bool foundSrvType = false;
|
||||
bool foundConIdType = false;
|
||||
_at.cmd_start_stop("^SISS", "?");
|
||||
_at.resp_start("^SISS:");
|
||||
/*
|
||||
* Profile is a list of tag-value map:
|
||||
* ^SISS: <srvProfileId>, <srvParmTag>, <srvParmValue>
|
||||
* [^SISS: ...]
|
||||
*/
|
||||
while (_at.info_resp()) {
|
||||
int id = _at.read_int();
|
||||
if (id == internet_service_id) {
|
||||
char paramTag[16];
|
||||
int paramTagLen = _at.read_string(paramTag, sizeof(paramTag));
|
||||
if (paramTagLen > 0) {
|
||||
char paramValue[100 + 1]; // APN may be up to 100 chars
|
||||
int paramValueLen = _at.read_string(paramValue, sizeof(paramValue));
|
||||
if (paramValueLen >= 0) {
|
||||
if (strcmp(paramTag, "srvType") == 0) {
|
||||
if (strcmp(paramValue, "Socket") == 0) {
|
||||
foundSrvType = true;
|
||||
}
|
||||
}
|
||||
if (strcmp(paramTag, "address") == 0) {
|
||||
if (strncmp(paramValue, "sock", sizeof("sock")) == 0) {
|
||||
foundSrvType = true;
|
||||
}
|
||||
}
|
||||
if (strcmp(paramTag, "conId") == 0) {
|
||||
char buf[10];
|
||||
std::sprintf(buf, "%d", _cid);
|
||||
if (strcmp(paramValue, buf) == 0) {
|
||||
foundConIdType = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
if (!foundSrvType) {
|
||||
_at.at_cmd_discard("^SISS", "=", "%d%s%s", internet_service_id, "srvType", "Socket");
|
||||
}
|
||||
|
||||
if (!foundConIdType) {
|
||||
_at.at_cmd_discard("^SISS", "=", "%d%s%d", internet_service_id, "conId", _cid);
|
||||
}
|
||||
|
||||
// host address (IPv4) and local+remote port is needed only for BGS2 which does not support UDP server socket
|
||||
char sock_addr[sizeof("sockudp://") - 1 + NSAPI_IPv6_SIZE + sizeof("[]:12345;port=12345") - 1 + 1];
|
||||
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
if (GEMALTO_CINTERION::get_module() != GEMALTO_CINTERION::ModuleBGS2) {
|
||||
std::sprintf(sock_addr, "sockudp://%s:%u", address ? address->get_ip_address() : "", socket->localAddress.get_port());
|
||||
} else {
|
||||
std::sprintf(sock_addr, "sockudp://%s:%u;port=%u", address->get_ip_address(), address->get_port(), socket->localAddress.get_port());
|
||||
}
|
||||
} else {
|
||||
if (address->get_ip_version() == NSAPI_IPv4) {
|
||||
std::sprintf(sock_addr, "socktcp://%s:%u", address->get_ip_address(), address->get_port());
|
||||
} else {
|
||||
std::sprintf(sock_addr, "socktcp://[%s]:%u", address->get_ip_address(), address->get_port());
|
||||
}
|
||||
}
|
||||
|
||||
_at.cmd_start("AT^SISS=");
|
||||
_at.write_int(internet_service_id);
|
||||
_at.write_string("address", false);
|
||||
_at.write_string(sock_addr);
|
||||
_at.cmd_stop_read_resp();
|
||||
|
||||
_at.at_cmd_discard("^SISO", "=", "%d", internet_service_id);
|
||||
|
||||
if (_at.get_last_error()) {
|
||||
tr_error("Socket %d open failed!", internet_service_id);
|
||||
_at.clear_error();
|
||||
socket_close_impl(internet_service_id); // socket may already be open on modem if app and modem are not in sync, as a recovery, try to close the socket so open succeeds the next time
|
||||
if (retry_open--) {
|
||||
goto retry_open;
|
||||
}
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
|
||||
socket->id = internet_service_id;
|
||||
tr_debug("Cinterion open %d (err %d)", socket->id, _at.get_last_error());
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
// To open socket:
|
||||
// 1. Select URC mode or polling mode with AT^SCFG
|
||||
// 2. create a GPRS connection profile with AT^SICS (must have PDP)
|
||||
// 3. create service profile with AT^SISS and map connectionID to serviceID
|
||||
// 4. open internet session with AT^SISO (ELS61 tries to attach to a packet domain)
|
||||
nsapi_error_t GEMALTO_CINTERION_CellularStack::create_socket_impl(CellularSocket *socket)
|
||||
{
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
if (GEMALTO_CINTERION::get_module() != GEMALTO_CINTERION::ModuleBGS2) {
|
||||
return socket_open_defer(socket);
|
||||
}
|
||||
}
|
||||
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_sendto_impl(CellularSocket *socket,
|
||||
const SocketAddress &address, const void *data, nsapi_size_t size)
|
||||
{
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
const int ip_version = address.get_ip_version();
|
||||
if (_stack_type != IPV4V6_STACK &&
|
||||
((ip_version == NSAPI_IPv4 && _stack_type != IPV4_STACK) ||
|
||||
(ip_version == NSAPI_IPv6 && _stack_type != IPV6_STACK))) {
|
||||
tr_warn("No IP route for %s", address.get_ip_address());
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
}
|
||||
|
||||
if (socket->proto == NSAPI_UDP && GEMALTO_CINTERION::get_module() == GEMALTO_CINTERION::ModuleBGS2) {
|
||||
tr_debug("Send addr %s, prev addr %s", address.get_ip_address(), socket->remoteAddress.get_ip_address());
|
||||
if (address != socket->remoteAddress) {
|
||||
if (socket->started) {
|
||||
socket_close_impl(socket->id);
|
||||
_at.clear_error();
|
||||
}
|
||||
|
||||
if (create_socket_impl(socket) != NSAPI_ERROR_OK) {
|
||||
tr_error("Failed to create socket %d", socket->id);
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
if (socket_open_defer(socket, &address) != NSAPI_ERROR_OK) {
|
||||
tr_error("Failed to open socket %d", socket->id);
|
||||
return NSAPI_ERROR_NO_SOCKET;
|
||||
}
|
||||
socket->remoteAddress = address;
|
||||
_at.resp_start("^SISW:");
|
||||
int sock_id = _at.read_int();
|
||||
MBED_ASSERT(sock_id == socket->id);
|
||||
int urc_code = _at.read_int();
|
||||
tr_debug("TX ready: socket=%d, urc=%d (err=%d)", sock_id, urc_code, _at.get_last_error());
|
||||
(void)sock_id;
|
||||
(void)urc_code;
|
||||
socket->started = true;
|
||||
socket->tx_ready = true;
|
||||
}
|
||||
}
|
||||
if (!socket->started || !socket->tx_ready) {
|
||||
tr_debug("Socket %d send would block (started %d, tx %d)", socket->id, socket->started, socket->tx_ready);
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
if (size > UDP_PACKET_SIZE) {
|
||||
tr_error("sendto size %d (max %d)", size, UDP_PACKET_SIZE);
|
||||
return NSAPI_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
_at.set_at_timeout(FAILURE_TIMEOUT);
|
||||
|
||||
if (GEMALTO_CINTERION::get_module() != GEMALTO_CINTERION::ModuleBGS2) {
|
||||
// UDP requires Udp_RemClient
|
||||
if (socket->proto == NSAPI_UDP) {
|
||||
char socket_address[NSAPI_IPv6_SIZE + sizeof("[]:12345") - 1 + 1];
|
||||
if (address.get_ip_version() == NSAPI_IPv4) {
|
||||
std::sprintf(socket_address, "%s:%u", address.get_ip_address(), address.get_port());
|
||||
} else {
|
||||
std::sprintf(socket_address, "[%s]:%u", address.get_ip_address(), address.get_port());
|
||||
}
|
||||
_at.cmd_start_stop("^SISW", "=", "%d%d%d%s", socket->id, size, 0, socket_address);
|
||||
} else {
|
||||
_at.cmd_start_stop("^SISW", "=", "%d%d%d", socket->id, size, 0);
|
||||
}
|
||||
} else {
|
||||
_at.cmd_start_stop("^SISW", "=", "%d%d", socket->id, size);
|
||||
}
|
||||
|
||||
sisw_retry:
|
||||
_at.resp_start("^SISW:");
|
||||
if (!_at.info_resp()) {
|
||||
tr_error("Socket %d send failure", socket->id);
|
||||
_at.restore_at_timeout();
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
int socket_id = _at.read_int();
|
||||
if (socket_id != socket->id) {
|
||||
// We might have read the SISW URC so let's try to handle it
|
||||
const int urc_code = _at.read_int();
|
||||
const int extra = _at.read_int();
|
||||
if (urc_code != -1 && extra == -1) {
|
||||
sisw_urc_handler(socket_id, urc_code);
|
||||
goto sisw_retry;
|
||||
}
|
||||
_at.restore_at_timeout();
|
||||
tr_error("Socket id %d != %d", socket_id, socket->id);
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
int accept_len = _at.read_int();
|
||||
if (accept_len == -1) {
|
||||
tr_error("Socket %d send failed", socket->id);
|
||||
_at.restore_at_timeout();
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
_at.skip_param(); // unackData
|
||||
|
||||
_at.write_bytes((uint8_t *)data, accept_len);
|
||||
_at.resp_stop();
|
||||
_at.restore_at_timeout();
|
||||
|
||||
if (_at.get_last_error() == NSAPI_ERROR_OK) {
|
||||
socket->tx_ready = false;
|
||||
}
|
||||
|
||||
return (_at.get_last_error() == NSAPI_ERROR_OK) ? accept_len : NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t GEMALTO_CINTERION_CellularStack::socket_recvfrom_impl(CellularSocket *socket, SocketAddress *address,
|
||||
void *buffer, nsapi_size_t size)
|
||||
{
|
||||
// AT_CellularStack::recvfrom(...) will make sure that we do have a socket
|
||||
// open on the modem, assert here to catch a programming error
|
||||
MBED_ASSERT(socket->id != -1);
|
||||
|
||||
// we must use this flag, otherwise ^SISR URC can come while we are reading response and there is
|
||||
// no way to detect if that is really an URC or response
|
||||
if (!socket->pending_bytes) {
|
||||
_at.process_oob(); // check for ^SISR URC
|
||||
if (!socket->pending_bytes) {
|
||||
tr_debug("Socket %d recv would block", socket->id);
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
}
|
||||
}
|
||||
|
||||
if (size > UDP_PACKET_SIZE) {
|
||||
size = UDP_PACKET_SIZE;
|
||||
}
|
||||
|
||||
_at.cmd_start_stop("^SISR", "=", "%d%d", socket->id, size);
|
||||
|
||||
sisr_retry:
|
||||
_at.resp_start("^SISR:");
|
||||
if (!_at.info_resp()) {
|
||||
tr_error("Socket %d not responding", socket->id);
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
int socket_id = _at.read_int();
|
||||
if (socket_id != socket->id) {
|
||||
const int urc_code = _at.read_int();
|
||||
const int extra = _at.read_int(); // should be -1 if URC
|
||||
if (urc_code != -1 && extra == -1) {
|
||||
sisr_urc_handler(socket_id, urc_code);
|
||||
goto sisr_retry;
|
||||
}
|
||||
tr_error("Socket recvfrom id %d != %d", socket_id, socket->id);
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t len = _at.read_int();
|
||||
if (len == 0) {
|
||||
tr_warn("Socket %d no data", socket->id);
|
||||
_at.resp_stop();
|
||||
return NSAPI_ERROR_WOULD_BLOCK;
|
||||
}
|
||||
if (len == -1) {
|
||||
tr_error("Socket %d recvfrom failed!", socket->id);
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
socket->pending_bytes = 0;
|
||||
if (len >= (nsapi_size_or_error_t)size) {
|
||||
len = (nsapi_size_or_error_t)size;
|
||||
int remain_len = _at.read_int();
|
||||
if (remain_len > 0) {
|
||||
socket->pending_bytes = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// UDP Udp_RemClient
|
||||
if (socket->proto == NSAPI_UDP && GEMALTO_CINTERION::get_module() != GEMALTO_CINTERION::ModuleBGS2) {
|
||||
char ip_address[NSAPI_IPv6_SIZE + sizeof("[]:12345") - 1 + 1];
|
||||
int ip_len = _at.read_string(ip_address, sizeof(ip_address));
|
||||
if (ip_len <= 0) {
|
||||
tr_error("Socket %d recvfrom addr (len %d)", socket->id, ip_len);
|
||||
return NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
if (address) {
|
||||
char *ip_start = ip_address;
|
||||
char *ip_stop;
|
||||
char *port_start;
|
||||
if (_stack_type == IPV6_STACK) {
|
||||
ip_start++; // skip '['
|
||||
ip_stop = strchr(ip_address, ']');
|
||||
if (ip_stop) {
|
||||
port_start = strchr(ip_stop, ':');
|
||||
}
|
||||
} else {
|
||||
ip_stop = strchr(ip_address, ':');
|
||||
port_start = ip_stop;
|
||||
}
|
||||
if (ip_stop && port_start) {
|
||||
char tmp_ch = *ip_stop;
|
||||
*ip_stop = '\0'; // split IP and port
|
||||
address->set_ip_address(ip_start);
|
||||
port_start++; // skip ':'
|
||||
int port = std::strtol(port_start, NULL, 10);
|
||||
address->set_port(port);
|
||||
*ip_stop = tmp_ch; // restore original IP string
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (address) {
|
||||
*address = socket->remoteAddress;
|
||||
}
|
||||
}
|
||||
|
||||
nsapi_size_or_error_t recv_len = _at.read_bytes((uint8_t *)buffer, len);
|
||||
|
||||
_at.resp_stop();
|
||||
|
||||
return (_at.get_last_error() == NSAPI_ERROR_OK) ? (recv_len ? recv_len : NSAPI_ERROR_WOULD_BLOCK) : NSAPI_ERROR_DEVICE_ERROR;
|
||||
}
|
||||
|
||||
// setup internet connection profile for sockets
|
||||
nsapi_error_t GEMALTO_CINTERION_CellularStack::create_connection_profile(int connection_profile_id)
|
||||
{
|
||||
if (GEMALTO_CINTERION::get_module() == GEMALTO_CINTERION::ModuleEMS31) {
|
||||
// EMS31 connection has only DNS settings and there is no need to modify those here for now
|
||||
return NSAPI_ERROR_OK;
|
||||
}
|
||||
|
||||
char conParamType[sizeof("GPRS0") + 1];
|
||||
std::sprintf(conParamType, "GPRS%d", (_stack_type == IPV4_STACK) ? 0 : 6);
|
||||
|
||||
_at.cmd_start_stop("^SICS", "?");
|
||||
bool found_connection = false;
|
||||
_at.resp_start("^SICS:");
|
||||
while (_at.info_resp()) {
|
||||
int id = _at.read_int();
|
||||
if (id == connection_profile_id) {
|
||||
char paramTag[16];
|
||||
int paramTagLen = _at.read_string(paramTag, sizeof(paramTag));
|
||||
if (paramTagLen > 0) {
|
||||
char paramValue[100 + 1]; // APN may be up to 100 chars
|
||||
int paramValueLen = _at.read_string(paramValue, sizeof(paramValue));
|
||||
if (paramValueLen >= 0) {
|
||||
if (strcmp(paramTag, "conType") == 0) {
|
||||
if (strcmp(paramValue, conParamType) == 0) {
|
||||
found_connection = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_at.resp_stop();
|
||||
|
||||
// connection profile is bound to a PDP context and it can not be changed
|
||||
if (!found_connection) {
|
||||
_at.at_cmd_discard("^SICS", "=", "%d%s%s", connection_profile_id, "conType", conParamType);
|
||||
|
||||
if (_apn && strlen(_apn) > 0) {
|
||||
_at.at_cmd_discard("^SICS", "=", "%d%s%s", connection_profile_id, "apn", _apn);
|
||||
}
|
||||
|
||||
if (_user && strlen(_user) > 0) {
|
||||
_at.at_cmd_discard("^SICS", "=", "%d%s%s", connection_profile_id, "user", _user);
|
||||
}
|
||||
|
||||
if (_password && strlen(_password) > 0) {
|
||||
_at.at_cmd_discard("^SICS", "=", "%d%s%s", connection_profile_id, "passwd", _password);
|
||||
}
|
||||
|
||||
// set maximum inactivity timeout
|
||||
_at.at_cmd_discard("^SICS", "=", "%d%s%d", connection_profile_id, "inactTO", 0xffff);
|
||||
|
||||
// use URC mode ON
|
||||
_at.at_cmd_discard("^SCFG", "=", "%s%s", "Tcp/withURCs", "on");
|
||||
}
|
||||
|
||||
tr_debug("Cinterion profile %d, %s (err %d)", connection_profile_id, (_stack_type == IPV4_STACK) ? "IPv4" : "IPv6", _at.get_last_error());
|
||||
return _at.get_last_error();
|
||||
}
|
||||
|
||||
void GEMALTO_CINTERION_CellularStack::close_connection_profile(int connection_profile_id)
|
||||
{
|
||||
if (GEMALTO_CINTERION::get_module() == GEMALTO_CINTERION::ModuleEMS31) {
|
||||
return;
|
||||
}
|
||||
|
||||
// To clear connection profile need to detach from packet data.
|
||||
// After detach modem sends PDP disconnected event to network class,
|
||||
// which propagates network disconnected to upper layer to start reconnecting.
|
||||
_at.at_cmd_discard("+CGATT", "=0");
|
||||
_at.clear_error();
|
||||
|
||||
_at.at_cmd_discard("^SICS", "=", "%d%s%s", connection_profile_id, "conType", "none");
|
||||
|
||||
_at.clear_error();
|
||||
}
|
||||
|
||||
nsapi_error_t GEMALTO_CINTERION_CellularStack::socket_connect(nsapi_socket_t handle, const SocketAddress &address)
|
||||
{
|
||||
int err = NSAPI_ERROR_DEVICE_ERROR;
|
||||
|
||||
struct CellularSocket *socket = (struct CellularSocket *)handle;
|
||||
if (!socket) {
|
||||
return err;
|
||||
}
|
||||
|
||||
_at.lock();
|
||||
err = create_socket_impl(socket);
|
||||
if (err != NSAPI_ERROR_OK) {
|
||||
_at.unlock();
|
||||
return err;
|
||||
}
|
||||
err = socket_open_defer(socket, &address);
|
||||
_at.unlock();
|
||||
|
||||
if (err == NSAPI_ERROR_OK) {
|
||||
socket->remoteAddress = address;
|
||||
socket->connected = true;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef GEMALTO_CINTERION_CELLULAR_STACK_H_
|
||||
#define GEMALTO_CINTERION_CELLULAR_STACK_H_
|
||||
|
||||
#include "AT_CellularStack.h"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
class GEMALTO_CINTERION_CellularStack : public AT_CellularStack {
|
||||
public:
|
||||
GEMALTO_CINTERION_CellularStack(ATHandler &atHandler, const char *apn, const char *username,
|
||||
const char *password, int cid, nsapi_ip_stack_t stack_type, AT_CellularDevice &device);
|
||||
virtual ~GEMALTO_CINTERION_CellularStack();
|
||||
|
||||
/** Initialize
|
||||
* Must be called immediately after constructor to initialize IP stack on the modem.
|
||||
* @return NSAPI_ERROR_OK on success
|
||||
*/
|
||||
nsapi_error_t socket_stack_init();
|
||||
|
||||
protected:
|
||||
|
||||
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);
|
||||
|
||||
virtual nsapi_error_t socket_connect(nsapi_socket_t handle, const SocketAddress &address);
|
||||
|
||||
private:
|
||||
// socket URC handlers as per Cinterion AT manuals
|
||||
void urc_sis();
|
||||
void urc_sisw();
|
||||
void sisw_urc_handler(int sock_id, int urc_code);
|
||||
void urc_sisr();
|
||||
void sisr_urc_handler(int sock_id, int urc_code);
|
||||
|
||||
// sockets need a connection profile, one profile is enough to support single stack sockets
|
||||
nsapi_error_t create_connection_profile(int connection_profile_id);
|
||||
void close_connection_profile(int connection_profile_id);
|
||||
|
||||
// socket open need to be deferred until sendto due to BGS2 does not support UDP server endpoint
|
||||
nsapi_error_t socket_open_defer(CellularSocket *socket, const SocketAddress *address = NULL);
|
||||
|
||||
// connection profile configuration needs Access Point Name, User Name and Password
|
||||
const char *_apn;
|
||||
const char *_user;
|
||||
const char *_password;
|
||||
};
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif /* GEMALTO_CINTERION_CELLULAR_STACK_H_ */
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "GEMALTO_CINTERION",
|
||||
"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
|
||||
},
|
||||
"baudrate" : {
|
||||
"help": "Serial connection baud rate",
|
||||
"value": 115200
|
||||
},
|
||||
"provide-default": {
|
||||
"help": "Provide as default CellularDevice [true/false]",
|
||||
"value": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user