[bc28] Modified base on comments

This commit is contained in:
luhuadong 2020-04-03 09:14:08 +08:00
parent 44d0bc3128
commit 4765eebdc1
2 changed files with 115 additions and 100 deletions

View File

@ -36,16 +36,6 @@
#define BC28_THREAD_STACK_SIZE 2048 #define BC28_THREAD_STACK_SIZE 2048
#define BC28_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX/2) #define BC28_THREAD_PRIORITY (RT_THREAD_PRIORITY_MAX/2)
static int bc28_power_on(struct at_device *device)
{
return(RT_EOK);
}
static int bc28_power_off(struct at_device *device)
{
return(RT_EOK);
}
static int bc28_sleep(struct at_device *device) static int bc28_sleep(struct at_device *device)
{ {
return(RT_EOK); return(RT_EOK);
@ -64,6 +54,7 @@ static int bc28_reset(struct at_device *device)
rt_pin_write(bc28->power_pin, PIN_HIGH); rt_pin_write(bc28->power_pin, PIN_HIGH);
rt_thread_mdelay(300); rt_thread_mdelay(300);
rt_pin_write(bc28->power_pin, PIN_LOW); rt_pin_write(bc28->power_pin, PIN_LOW);
bc28->power_status = 1;
return(RT_EOK); return(RT_EOK);
} }
@ -77,7 +68,7 @@ static int bc28_check_link_status(struct at_device *device)
bc28 = (struct at_device_bc28 *)device->user_data; bc28 = (struct at_device_bc28 *)device->user_data;
if ( ! bc28->power_status) // power off if ( ! bc28->power_status) // power off
{ {
LOG_D("the power is off."); LOG_E("the power is off.");
return(-RT_ERROR); return(-RT_ERROR);
} }
if (bc28->sleep_status) // is sleep status if (bc28->sleep_status) // is sleep status
@ -94,7 +85,7 @@ static int bc28_check_link_status(struct at_device *device)
resp = at_create_resp(64, 0, rt_tick_from_millisecond(300)); resp = at_create_resp(64, 0, rt_tick_from_millisecond(300));
if (resp == RT_NULL) if (resp == RT_NULL)
{ {
LOG_D("no memory for resp create."); LOG_E("no memory for resp create.");
return(-RT_ERROR); return(-RT_ERROR);
} }
@ -110,17 +101,8 @@ static int bc28_check_link_status(struct at_device *device)
} }
} }
} }
#if 0
if (bc28->sleep_status) // is sleep status
{
if (at_obj_exec_cmd(device->client, resp, "AT+QRELLOCK") != RT_EOK)
{
LOG_D("startup entry into sleep fail.");
}
}
#endif
at_delete_resp(resp);
at_delete_resp(resp);
return(result); return(result);
} }
@ -129,7 +111,7 @@ static int bc28_check_link_status(struct at_device *device)
static int bc28_netdev_set_info(struct netdev *netdev) static int bc28_netdev_set_info(struct netdev *netdev)
{ {
#define BC28_INFO_RESP_SIZE 128 #define BC28_INFO_RESP_SIZE 128
#define BC28_INFO_RESP_TIMOUT rt_tick_from_millisecond(300) #define BC28_INFO_RESP_TIMOUT rt_tick_from_millisecond(5000)
int result = RT_EOK; int result = RT_EOK;
ip_addr_t addr; ip_addr_t addr;
@ -239,13 +221,13 @@ static int bc28_netdev_set_info(struct netdev *netdev)
/* parse response data "PrimaryDns:<pri_dns>" /* parse response data "PrimaryDns:<pri_dns>"
* "SecondaryDns:<sec_dns>" * "SecondaryDns:<sec_dns>"
*/ */
if (at_resp_parse_line_args_by_kw(resp, "PrimaryDns:", "PrimaryDns:\"%[^\"]\"", dns_server1) <= 0) if (at_resp_parse_line_args_by_kw(resp, "PrimaryDns:", "PrimaryDns: %s", dns_server1) <= 0)
{ {
LOG_E("%s device prase \"AT+QIDNSCFG?\" cmd error.", device->name); LOG_E("%s device prase \"AT+QIDNSCFG?\" cmd error.", device->name);
result = -RT_ERROR; result = -RT_ERROR;
goto __exit; goto __exit;
} }
if (at_resp_parse_line_args_by_kw(resp, "SecondaryDns:", "SecondaryDns:\"%[^\"]\"", dns_server2) <= 0) if (at_resp_parse_line_args_by_kw(resp, "SecondaryDns:", "SecondaryDns: %s", dns_server2) <= 0)
{ {
LOG_E("%s device prase \"AT+QIDNSCFG?\" cmd error.", device->name); LOG_E("%s device prase \"AT+QIDNSCFG?\" cmd error.", device->name);
result = -RT_ERROR; result = -RT_ERROR;
@ -357,7 +339,7 @@ static int bc28_netdev_set_down(struct netdev *netdev)
if (device->is_init == RT_TRUE) if (device->is_init == RT_TRUE)
{ {
bc28_power_off(device); //bc28_power_off(device);
device->is_init = RT_FALSE; device->is_init = RT_FALSE;
netdev_low_level_set_status(netdev, RT_FALSE); netdev_low_level_set_status(netdev, RT_FALSE);
@ -389,7 +371,7 @@ static int bc28_netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, ip
resp = at_create_resp(BC28_DNS_RESP_LEN, 0, BC28_DNS_RESP_TIMEOUT); resp = at_create_resp(BC28_DNS_RESP_LEN, 0, BC28_DNS_RESP_TIMEOUT);
if (resp == RT_NULL) if (resp == RT_NULL)
{ {
LOG_D("no memory for resp create."); LOG_E("no memory for resp create.");
result = -RT_ENOMEM; result = -RT_ENOMEM;
goto __exit; goto __exit;
} }
@ -413,13 +395,16 @@ __exit:
return result; return result;
} }
#ifdef AT_USING_SOCKET
int bc28_domain_resolve(const char *name, char ip[16]);
#endif
#ifdef NETDEV_USING_PING #ifdef NETDEV_USING_PING
static int bc28_netdev_ping(struct netdev *netdev, const char *host, static int bc28_netdev_ping(struct netdev *netdev, const char *host,
size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp) size_t data_len, uint32_t timeout, struct netdev_ping_resp *ping_resp)
{ {
#define BC28_PING_RESP_SIZE 128 #define BC28_PING_RESP_SIZE 128
#define BC28_PING_IP_SIZE 16 #define BC28_PING_IP_SIZE 16
#define BC28_PING_TIMEOUT (5 * RT_TICK_PER_SECOND) #define BC28_PING_TIMEOUT (10 * RT_TICK_PER_SECOND)
rt_err_t result = RT_EOK; rt_err_t result = RT_EOK;
int response = -1, recv_data_len, ping_time, ttl; int response = -1, recv_data_len, ping_time, ttl;
@ -445,43 +430,53 @@ static int bc28_netdev_ping(struct netdev *netdev, const char *host,
return -RT_ENOMEM; return -RT_ENOMEM;
} }
/* send "AT+NPING=<remote_address>[,<p_size>[,<timeout>]]" commond to send ping request */ /* DNS resolve */
if (at_obj_exec_cmd(device->client, resp, "AT+NPING=\"%s\",12,%d", host, timeout / RT_TICK_PER_SECOND) < 0) struct in_addr inp;
if (inet_aton(host, &inp) > 0)
{
rt_strncpy(ip_addr, host, BC28_PING_IP_SIZE);
}
#ifdef AT_USING_SOCKET
else
{
bc28_domain_resolve(host, ip_addr);
}
#endif
if (at_obj_exec_cmd(device->client, resp, "AT+NPING=%s,%d,%d",
ip_addr, data_len, timeout*1000/RT_TICK_PER_SECOND) < 0)
{ {
result = -RT_ERROR; result = -RT_ERROR;
goto __exit; goto __exit;
} }
#if 0
at_resp_parse_line_args_by_kw(resp, "+NPING:", "+NPING:%d", &response);
/* Received the ping response from the server */
if (response == 0)
{
if (at_resp_parse_line_args_by_kw(resp, "+NPING:", "+NPING:\"%[^\"]\",%d,%d,%d",
ip_addr, &ttl, &ping_time) <= 0)
{
result = -RT_ERROR;
goto __exit;
}
}
/* prase response number */ if (at_resp_parse_line_args_by_kw(resp, "+NPINGERR:", "+NPINGERR:%d", &response) > 0)
{
switch (response) switch (response)
{ {
case 0: case 1:
inet_aton(ip_addr, &(ping_resp->ip_addr));
ping_resp->data_len = recv_data_len;
ping_resp->ticks = ping_time;
ping_resp->ttl = ttl;
result = RT_EOK;
break;
case 569:
result = -RT_ETIMEOUT; result = -RT_ETIMEOUT;
break; break;
case 2:
default: default:
result = -RT_ERROR; result = -RT_ERROR;
break; break;
} }
#endif }
else if (at_resp_parse_line_args_by_kw(resp, "+NPING:", "+NPING:%[^,],%d,%d",
ip_addr, &ttl, &ping_time) > 0 )
{
inet_aton(ip_addr, &(ping_resp->ip_addr));
ping_resp->data_len = data_len;
ping_resp->ticks = rt_tick_from_millisecond(ping_time);
ping_resp->ttl = ttl;
result = RT_EOK;
}
else
{
result = -RT_ERROR;
goto __exit;
}
__exit: __exit:
if (resp) if (resp)
@ -536,7 +531,7 @@ static struct netdev *bc28_netdev_add(const char *netdev_name)
return netdev; return netdev;
} }
/* ============================= bc26 device operations ============================= */ /* ============================= bc28 device operations ============================= */
/* initialize for bc28 */ /* initialize for bc28 */
static void bc28_init_thread_entry(void *parameter) static void bc28_init_thread_entry(void *parameter)
@ -546,6 +541,7 @@ static void bc28_init_thread_entry(void *parameter)
#define CSQ_RETRY 20 #define CSQ_RETRY 20
#define CGREG_RETRY 50 #define CGREG_RETRY 50
#define IPADDR_RETRY 10 #define IPADDR_RETRY 10
#define AT_DEFAULT_TIMEOUT 5000
int i; int i;
int retry_num = INIT_RETRY; int retry_num = INIT_RETRY;
@ -554,7 +550,7 @@ static void bc28_init_thread_entry(void *parameter)
struct at_device *device = (struct at_device *) parameter; struct at_device *device = (struct at_device *) parameter;
struct at_client *client = device->client; struct at_client *client = device->client;
resp = at_create_resp(128, 0, rt_tick_from_millisecond(300)); resp = at_create_resp(128, 0, rt_tick_from_millisecond(AT_DEFAULT_TIMEOUT));
if (resp == RT_NULL) if (resp == RT_NULL)
{ {
LOG_E("no memory for resp create."); LOG_E("no memory for resp create.");
@ -580,6 +576,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "ATE0") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "ATE0") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E("ATE0");
goto __exit; goto __exit;
} }
@ -587,6 +584,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "AT+QREGSWT=2") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+QREGSWT=2") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+QREGSWT=2");
goto __exit; goto __exit;
} }
@ -594,13 +592,24 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "AT+NCONFIG=AUTOCONNECT,FALSE") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+NCONFIG=AUTOCONNECT,FALSE") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+NCONFIG=AUTOCONNECT,FALSE");
goto __exit; goto __exit;
} }
/* reboot */
at_obj_exec_cmd(device->client, resp, "AT+NRB");
rt_thread_mdelay(5000);
while (at_obj_exec_cmd(device->client, resp, "AT") != RT_EOK)
{
rt_thread_mdelay(1000);
}
/* check IMEI */ /* check IMEI */
if (at_obj_exec_cmd(device->client, resp, "AT+CGSN=1") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+CGSN=1") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+CGSN=1");
goto __exit; goto __exit;
} }
@ -608,6 +617,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "AT+NBAND=8") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+NBAND=8") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+NBAND=8");
goto __exit; goto __exit;
} }
@ -615,6 +625,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "AT+CFUN=1") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+CFUN=1") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+CFUN=1");
goto __exit; goto __exit;
} }
@ -622,6 +633,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "AT+NSONMI=2") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+NSONMI=2") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+NSONMI=2");
goto __exit; goto __exit;
} }
@ -629,6 +641,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "AT+CEDRXS=0,5") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+CEDRXS=0,5") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+CEDRXS=0,5");
goto __exit; goto __exit;
} }
@ -636,6 +649,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "AT+CPSMS=0") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+CPSMS=0") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+CPSMS=0");
goto __exit; goto __exit;
} }
@ -643,6 +657,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "AT+CIMI") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+CIMI") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+CIMI");
goto __exit; goto __exit;
} }
@ -650,6 +665,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "AT+CGATT=1") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+CGATT=1") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+CGATT=1");
goto __exit; goto __exit;
} }
@ -657,6 +673,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "AT+NATSPEED?") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+NATSPEED?") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> AT+NATSPEED?");
goto __exit; goto __exit;
} }
at_resp_parse_line_args_by_kw(resp, "+NATSPEED:", "+NATSPEED:%d", &i); at_resp_parse_line_args_by_kw(resp, "+NATSPEED:", "+NATSPEED:%d", &i);
@ -666,6 +683,7 @@ static void bc28_init_thread_entry(void *parameter)
if (at_obj_exec_cmd(device->client, resp, "ATI") != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "ATI") != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
LOG_E(">> ATI");
goto __exit; goto __exit;
} }
for (i = 0; i < (int) resp->line_counts - 1; i++) for (i = 0; i < (int) resp->line_counts - 1; i++)
@ -773,7 +791,7 @@ static void bc28_init_thread_entry(void *parameter)
if (result != RT_EOK) if (result != RT_EOK)
{ {
/* power off the bc28 device */ /* power off the bc28 device */
bc28_power_off(device); //bc28_power_off(device);
rt_thread_mdelay(1000); rt_thread_mdelay(1000);
LOG_I("%s device initialize retry...", device->name); LOG_I("%s device initialize retry...", device->name);
@ -845,6 +863,24 @@ static int bc28_init(struct at_device *device)
#ifdef AT_USING_SOCKET #ifdef AT_USING_SOCKET
bc28_socket_init(device); bc28_socket_init(device);
#endif #endif
/* add bc28 device to the netdev list */
device->netdev = bc28_netdev_add(bc28->device_name);
if (device->netdev == RT_NULL)
{
LOG_E("add netdev(%s) failed.", bc28->device_name);
return -RT_ERROR;
}
/* initialize bc28 pin configuration */
if (bc28->power_pin != -1)
{
rt_pin_mode(bc28->power_pin, PIN_MODE_OUTPUT);
rt_pin_write(bc28->power_pin, PIN_LOW);
}
/* initialize bc28 device network */
return bc28_netdev_set_up(device->netdev);
} }
static int bc28_deinit(struct at_device *device) static int bc28_deinit(struct at_device *device)
@ -862,17 +898,13 @@ static int bc28_control(struct at_device *device, int cmd, void *arg)
switch (cmd) switch (cmd)
{ {
case AT_DEVICE_CTRL_SLEEP:
result = bc28_sleep(device);
break;
case AT_DEVICE_CTRL_WAKEUP:
result = bc28_wakeup(device);
break;
case AT_DEVICE_CTRL_POWER_ON:
case AT_DEVICE_CTRL_POWER_OFF:
case AT_DEVICE_CTRL_RESET: case AT_DEVICE_CTRL_RESET:
result = bc28_reset(device); result = bc28_reset(device);
break; break;
case AT_DEVICE_CTRL_SLEEP:
case AT_DEVICE_CTRL_WAKEUP:
case AT_DEVICE_CTRL_POWER_ON:
case AT_DEVICE_CTRL_POWER_OFF:
case AT_DEVICE_CTRL_LOW_POWER: case AT_DEVICE_CTRL_LOW_POWER:
case AT_DEVICE_CTRL_NET_CONN: case AT_DEVICE_CTRL_NET_CONN:
case AT_DEVICE_CTRL_NET_DISCONN: case AT_DEVICE_CTRL_NET_DISCONN:

View File

@ -130,7 +130,7 @@ static int bc28_socket_close(struct at_socket *socket)
return -RT_ENOMEM; return -RT_ENOMEM;
} }
result = at_obj_exec_cmd(device->client, resp, "AT+QICLOSE=%d", device_socket); result = at_obj_exec_cmd(device->client, resp, "AT+NSOCL=%d", device_socket);
at_delete_resp(resp); at_delete_resp(resp);
@ -172,16 +172,8 @@ static int bc28_socket_connect(struct at_socket *socket, char *ip, int32_t port,
return -RT_ERROR; return -RT_ERROR;
} }
switch(type) if (type != AT_SOCKET_TCP)
{ {
case AT_SOCKET_TCP:
type_str = "TCP";
break;
case AT_SOCKET_UDP:
type_str = "UDP";
break;
default:
LOG_E("%s device socket(%d) connect type error.", device->name, device_socket);
return -RT_ERROR; return -RT_ERROR;
} }
@ -198,8 +190,8 @@ static int bc28_socket_connect(struct at_socket *socket, char *ip, int32_t port,
event = SET_EVENT(device_socket, BC28_EVENT_CONN_OK | BC28_EVENT_CONN_FAIL); event = SET_EVENT(device_socket, BC28_EVENT_CONN_OK | BC28_EVENT_CONN_FAIL);
bc28_socket_event_recv(device, event, 0, RT_EVENT_FLAG_OR); bc28_socket_event_recv(device, event, 0, RT_EVENT_FLAG_OR);
if (at_obj_exec_cmd(device->client, resp, "AT+QIOPEN=1,%d,\"%s\",\"%s\",%d,0,1", if (at_obj_exec_cmd(device->client, resp, "AT+NSOCO=%d,%s,%d",
device_socket, type_str, ip, port) < 0) device_socket, ip, port) < 0)
{ {
result = -RT_ERROR; result = -RT_ERROR;
break; break;
@ -439,7 +431,7 @@ __exit:
* -2: wait socket event timeout * -2: wait socket event timeout
* -5: no memory * -5: no memory
*/ */
static int bc28_domain_resolve(const char *name, char ip[16]) int bc28_domain_resolve(const char *name, char ip[16])
{ {
#define RESOLVE_RETRY 3 #define RESOLVE_RETRY 3
@ -472,7 +464,7 @@ static int bc28_domain_resolve(const char *name, char ip[16])
bc28 = (struct at_device_bc28 *) device->user_data; bc28 = (struct at_device_bc28 *) device->user_data;
bc28->socket_data = ip; bc28->socket_data = ip;
if (at_obj_exec_cmd(device->client, resp, "AT+QIDNSGIP=1,\"%s\"", name) != RT_EOK) if (at_obj_exec_cmd(device->client, resp, "AT+QDNS=0,%s", name) != RT_EOK)
{ {
result = -RT_ERROR; result = -RT_ERROR;
goto __exit; goto __exit;
@ -704,30 +696,13 @@ static void urc_dnsqip_func(struct at_client *client, const char *data, rt_size_
return; return;
} }
for (i = 0; i < size; i++) sscanf(data, "+QDNS:%s", recv_ip);
{
if (*(data + i) == '.')
j++;
}
/* There would be several dns result, we just pickup one */
if (j == 3)
{
sscanf(data, "+QIURC: \"dnsgip\",\"%[^\"]", recv_ip);
recv_ip[15] = '\0'; recv_ip[15] = '\0';
rt_memcpy(bc28->socket_data, recv_ip, sizeof(recv_ip)); rt_memcpy(bc28->socket_data, recv_ip, sizeof(recv_ip));
bc28_socket_event_send(device, BC28_EVENT_DOMAIN_OK); bc28_socket_event_send(device, BC28_EVENT_DOMAIN_OK);
} }
else
{
sscanf(data, "+QIURC: \"dnsgip\",%d,%d,%d", &result, &ip_count, &dns_ttl);
if (result)
{
at_tcp_ip_errcode_parse(result);
}
}
}
static void urc_func(struct at_client *client, const char *data, rt_size_t size) static void urc_func(struct at_client *client, const char *data, rt_size_t size)
{ {
@ -736,6 +711,13 @@ static void urc_func(struct at_client *client, const char *data, rt_size_t size)
LOG_I("URC data : %.*s", size, data); LOG_I("URC data : %.*s", size, data);
} }
static void urc_dns_func(struct at_client *client, const char *data, rt_size_t size)
{
RT_ASSERT(data && size);
urc_dnsqip_func(client, data, size);
}
static void urc_qiurc_func(struct at_client *client, const char *data, rt_size_t size) static void urc_qiurc_func(struct at_client *client, const char *data, rt_size_t size)
{ {
RT_ASSERT(data && size); RT_ASSERT(data && size);
@ -755,6 +737,7 @@ static const struct at_urc urc_table[] =
{"SEND FAIL", "\r\n", urc_send_func}, {"SEND FAIL", "\r\n", urc_send_func},
{"+QIOPEN:", "\r\n", urc_connect_func}, {"+QIOPEN:", "\r\n", urc_connect_func},
{"+QIURC:", "\r\n", urc_qiurc_func}, {"+QIURC:", "\r\n", urc_qiurc_func},
{"+QDNS:", "\r\n", urc_dns_func},
}; };
static const struct at_socket_ops bc28_socket_ops = static const struct at_socket_ops bc28_socket_ops =