Skip to content

Commit

Permalink
Merge pull request #12 from sakura-internet/feat/obj_down
Browse files Browse the repository at this point in the history
ダウンリンク方向通信対応
  • Loading branch information
f-okuhara authored Oct 6, 2021
2 parents 0ac64d4 + 5c58e98 commit b1934d8
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 24 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ target_sources(app PRIVATE
src/registers.c
src/uart_broker.c
src/sipf/sipf_client_http.c
src/sipf/sipf_object.c
src/fota/fota_http.c
src/gnss/gnss.c
)
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,6 @@ For production
OR

Write the HEX image file 'build/{ENV}/zephyr/merged.hex' using nRF Connect `Programmer' application.

---
Please refer to the [Wiki(Japanese)](https://github.com/sakura-internet/sipf-std-client_nrf9160/wiki) for specifications.
8 changes: 1 addition & 7 deletions include/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,7 @@
#include <stdint.h>
#define CMD_BUFF_SZ 1024

typedef enum
{
CMD_STATE_WAIT = 0,
CMD_STATE_BUFFERING_ASCII,
CMD_STATE_BUFFERING_BIN,
_CMD_STATE_CNT_
} CmdState;
typedef enum { CMD_STATE_WAIT = 0, CMD_STATE_BUFFERING_ASCII, CMD_STATE_BUFFERING_BIN, _CMD_STATE_CNT_ } CmdState;

typedef struct
{
Expand Down
1 change: 1 addition & 0 deletions include/sipf/sipf_client_http.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ int SipfClientGetAuthInfo(void);
int SipfClientSetAuthInfo(const char *user_name, const char *passwd);
int SipfCLientObjUpRaw(uint8_t *payload_buffer, uint16_t size, SipfObjectOtid *otid);
int SipfClientObjUp(const SipfObjectUp *simp_obj_up, SipfObjectOtid *otid);
int SipfClientObjDown(SipfObjectOtid *otid, uint8_t *remains, uint8_t *objqty, uint8_t **p_objs, uint8_t **p_user_send_datetime, uint8_t **p_recv_datetime);

#endif
20 changes: 14 additions & 6 deletions include/sipf/sipf_object.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#ifndef _SIPF_OBJECT_H_
#define _SIPF_OBJECT_H_

#include <stdlib.h>
#include <stdint.h>
#include <string.h>

#define OBJ_TYPE_UINT8 0x00
#define OBJ_TYPE_INT8 0x01
Expand All @@ -16,15 +18,18 @@
#define OBJ_TYPE_BIN_BASE64 0x10
#define OBJ_TYPE_STR_UTF8 0x20

typedef enum
{
typedef enum {
OBJECTS_UP = 0x00,
OBJECTS_UP_RETRY = 0x01,
OBJID_NOTIFICATION = 0x02,
OBJID_REACH_INQUIRY = 0x03,
OBJID_REACH_RESULT = 0x04,
OBJECTS_DOWN = 0x05,
OBJID_REACH_NOTIFICATION = 0x06,

OBJECTS_DOWN_REQUEST = 0x11,
OBJECTS_DOWN = 0x12,
/*
OBJID_REACH_INQUIRY = 0xff,
OBJID_REACH_RESULT = 0xff,
OBJID_REACH_NOTIFICATION = 0xff,
*/
OBJ_COMMAND_ERR = 0xff,
} SipfObjectCommandType;

Expand Down Expand Up @@ -54,4 +59,7 @@ typedef struct
{
uint8_t value[16];
} SipfObjectOtid;

int SipfObjectParse(uint8_t *raw_buff, const uint16_t raw_len, SipfObjectObject *obj);

#endif
4 changes: 2 additions & 2 deletions prj.conf.base
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,5 @@ CONFIG_LTE_PSM_REQ_RAT="00000010"
## SIPF standard client ##
CONFIG_SIPF_APP_TYPE=0
CONFIG_SIPF_APP_VER_MAJOR=0
CONFIG_SIPF_APP_VER_MINOR=1
CONFIG_SIPF_APP_VER_RELEASE=1
CONFIG_SIPF_APP_VER_MINOR=2
CONFIG_SIPF_APP_VER_RELEASE=0
71 changes: 70 additions & 1 deletion src/cmd_ascii.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,75 @@ static int cmdAsciiCmdTxRaw(uint8_t *in_buff, uint16_t in_len, uint8_t *out_buff
return len;
}

/**
* $$RXコマンド
* パラメータなし
*/
static int cmdAsciiCmdRx(uint8_t *in_buff, uint16_t in_len, uint8_t *out_buff, uint16_t out_buff_len)
{
if (in_len != 0) {
// なにかパラメータが指定されてる。
return cmdCreateResIllParam(out_buff, out_buff_len);
}

uint8_t err;
SipfObjectOtid otid;
uint8_t remains, objqty;
uint8_t *p_snd_datetime, *p_rcv_datetime, *p_objs[16];

err = SipfClientObjDown(&otid, &remains, &objqty, p_objs, &p_snd_datetime, &p_rcv_datetime);

if (err != 0) {
LOG_ERR("SipfClientObjDown():%d", err);
return cmdCreateResNg(out_buff, out_buff_len);
}

LOG_INF("remains=%d, objqty=%d", remains, objqty);

if (objqty == 0) {
LOG_INF("EMPTY");
return cmdCreateResOk(out_buff, out_buff_len);
}

int idx = 0;
// OTID
for (int i = 0; i < 16; i++) {
idx += sprintf(&out_buff[idx], "%02X", otid.value[i]);
}
idx += sprintf(&out_buff[idx], "\r\n");
// USER_SEND_DATETIME_MS
for (int i = 0; i < 8; i++) {
idx += sprintf(&out_buff[idx], "%02X", p_snd_datetime[i]);
}
idx += sprintf(&out_buff[idx], "\r\n");
// RECEIVE_DATETIME_MS
for (int i = 0; i < 8; i++) {
idx += sprintf(&out_buff[idx], "%02X", p_rcv_datetime[i]);
}
idx += sprintf(&out_buff[idx], "\r\n");
// REMAINS
idx += sprintf(&out_buff[idx], "%02X\r\n", remains);
// OBJQTY
idx += sprintf(&out_buff[idx], "%02X\r\n", objqty);
// OBJECTS
for (int i = 0; i < objqty; i++) {
SipfObjectObject obj;
obj.value = buff_work;
if (SipfObjectParse(p_objs[i], sizeof(buff_work), &obj) != 0) {
LOG_ERR("SipfObjectParse() failed...");
return cmdCreateResNg(out_buff, out_buff_len);
}
idx += sprintf(&out_buff[idx], "%02x %02x %02x ", obj.obj_type, obj.obj_tagid, obj.value_len);
for (int j = 0; j < obj.value_len; j++) {
idx += sprintf(&out_buff[idx], "%02X", obj.value[j]);
}
idx += sprintf(&out_buff[idx], "\r\n");
}
idx += sprintf(&out_buff[idx], "OK\r\n");

return idx;
}

/**
* $$UNLOCKコマンド
* in_buff: コマンド名より後ろを格納してるバッファ
Expand Down Expand Up @@ -486,7 +555,7 @@ static int cmdAsciiCmdGnssNmea(uint8_t *in_buff, uint16_t in_len, uint8_t *out_b
return (int)(buff - out_buff);
}

static CmdAsciiCmd cmdfunc[] = {{CMD_REG_W, cmdAsciiCmdW}, {CMD_REG_R, cmdAsciiCmdR}, {CMD_TXRAW, cmdAsciiCmdTxRaw}, {CMD_TX, cmdAsciiCmdTx}, {CMD_UNLOCK, cmdAsciiCmdUnlock}, {CMD_UPDATE, cmdAsciiCmdUpdate}, {CMD_GNSS_ENABLE, cmdAsciiCmdGnssEnable}, {CMD_GNSS_GET_LOCATION, cmdAsciiCmdGnssLocation}, {CMD_GNSS_GET_NMEA, cmdAsciiCmdGnssNmea}, {CMD_GNSS_GET_STATUS, cmdAsciiCmdGnssStatus}, {NULL, NULL}};
static CmdAsciiCmd cmdfunc[] = {{CMD_REG_W, cmdAsciiCmdW}, {CMD_REG_R, cmdAsciiCmdR}, {CMD_TXRAW, cmdAsciiCmdTxRaw}, {CMD_TX, cmdAsciiCmdTx}, {CMD_RX, cmdAsciiCmdRx}, {CMD_UNLOCK, cmdAsciiCmdUnlock}, {CMD_UPDATE, cmdAsciiCmdUpdate}, {CMD_GNSS_ENABLE, cmdAsciiCmdGnssEnable}, {CMD_GNSS_GET_LOCATION, cmdAsciiCmdGnssLocation}, {CMD_GNSS_GET_NMEA, cmdAsciiCmdGnssNmea}, {CMD_GNSS_GET_STATUS, cmdAsciiCmdGnssStatus}, {NULL, NULL}};

int CmdAsciiParse(uint8_t *in_buff, uint16_t in_len, uint8_t *out_buff, uint16_t out_buff_len)
{
Expand Down
1 change: 0 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,6 @@ void main(void)
uint8_t b, prev_auth_mode = 0x00;
UartBrokerPuts("+++ Ready +++\n");
led_on(LED3_PIN);

ms_timeout = k_uptime_get() + LED_HEARTBEAT_MS;
for (;;) {
while (UartBrokerGetByte(&b) == 0) {
Expand Down
133 changes: 126 additions & 7 deletions src/sipf/sipf_client_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,7 @@ static int run_http_request(const char *hostname, struct http_request *req, uint
int ret;
struct addrinfo *res;
struct addrinfo hints = {
.ai_family = AF_INET,
.ai_socktype = SOCK_STREAM,
.ai_family = AF_INET, .ai_socktype = SOCK_STREAM,
};
// 接続先をセットアップするよ
ret = getaddrinfo(hostname, NULL, &hints, &res);
Expand Down Expand Up @@ -171,7 +170,7 @@ static int run_connector_http_request(const uint8_t *payload, const int payload_
//パスワード認証モードの場合
createAuthInfoFromRegister(); //レジスタから認証情報を生成する
}
LOG_DBG("auth: %s", req_auth_header);
LOG_INF("auth: %s", req_auth_header);

struct http_request req;
memset(&req, 0, sizeof(req));
Expand Down Expand Up @@ -218,6 +217,7 @@ int SipfClientSetAuthInfo(const char *user_name, const char *passwd)
int ilen, olen;

ilen = sprintf(tmp1, "%s:%s", user_name, passwd);
LOG_DBG("%s", tmp1);
if (base64_encode(tmp2, sizeof(tmp2), &olen, tmp1, ilen) < 0) {
return -1;
}
Expand All @@ -235,9 +235,9 @@ int SipfClientGetAuthInfo(void)
return ret;
}

LOG_INF("Response status %s", http_res.http_status);
LOG_INF("content-length: %d", http_res.content_length);
// FIXME: CONFIG_SIPF_LOG_LEVEL をつかっていい感じに抑制する
LOG_DBG("Response status %s", http_res.http_status);
LOG_DBG("content-length: %d", http_res.content_length);
for (int i = 0; i < http_res.content_length; i++) {
LOG_DBG("0x%02x ", http_res.body_start[i]);
}
Expand All @@ -260,7 +260,7 @@ int SipfClientGetAuthInfo(void)
}
}
}
LOG_DBG("user_name=%s passwd=%s", user_name, passwd);
LOG_INF("user_name=%s passwd=%s", user_name, passwd);
if (passwd != NULL) {
return SipfClientSetAuthInfo(user_name, passwd);
}
Expand Down Expand Up @@ -328,7 +328,7 @@ int SipfCLientObjUpRaw(uint8_t *payload_buffer, uint16_t size, SipfObjectOtid *o
return -1;
}

if (sipf_obj_head[0] != 0x02) {
if (sipf_obj_head[0] != OBJID_NOTIFICATION) {
// OBJID_NOTIFICATIONじゃない
LOG_WRN("Invalid header type 0x%02x", sipf_obj_head[0]);
return -1;
Expand Down Expand Up @@ -370,3 +370,122 @@ int SipfClientObjUp(const SipfObjectUp *simp_obj_up, SipfObjectOtid *otid)

return SipfCLientObjUpRaw(payload, size, otid);
}

int SipfClientObjDown(SipfObjectOtid *otid, uint8_t *remains, uint8_t *objqty, uint8_t **p_objs, uint8_t **p_user_send_datetime, uint8_t **p_recv_datetime)
{
int ret;

if (otid == NULL) {
return -1;
}
if (objqty == NULL) {
return -1;
}
if (p_user_send_datetime == NULL) {
return -1;
}
if (p_recv_datetime == NULL) {
return -1;
}

memset(req_buff, 0x00, BUFF_SZ);

// COMMAND_TYPE
req_buff[0] = (uint8_t)OBJECTS_DOWN_REQUEST;
// COMMAND_TIME
req_buff[1] = 0x00;
req_buff[2] = 0x00;
req_buff[3] = 0x00;
req_buff[4] = 0x00;
req_buff[5] = 0x00;
req_buff[6] = 0x00;
req_buff[7] = 0x00;
req_buff[8] = 0x00;
// OPTION_FLAG
req_buff[9] = 0x00;
// PAYLOAD_SIZE(BigEndian)
req_buff[10] = 0x00;
req_buff[11] = 0x01;

// OBJECTS_DOWN
req_buff[12] = 0x00; // RESERVED

/* リクエスト送信 */
static struct http_response http_res;
ret = run_connector_http_request(req_buff, 13, &http_res);

LOG_INF("run_connector_http_request(): %d", ret);
if (ret < 0) {
return ret;
}

LOG_INF("Response status %s", http_res.http_status);
LOG_INF("content-length: %d", http_res.content_length);
for (int i = 0; i < http_res.content_length; i++) {
LOG_DBG("0x%02x ", http_res.body_start[i]);
}

/* レスポンスを処理 */
uint8_t *sipf_obj_head = &http_res.body_start[0];
uint8_t *sipf_obj_payload = &http_res.body_start[12];
if (strcmp(http_res.http_status, "OK") != 0) {
if (strcmp(http_res.http_status, "Unauthorized") == 0) {
return -401;
}
// OK以外
return -1;
}

// OBJECTS_DOWNをパース
if ((http_res.content_length < 12) || (http_res.content_length >= 12 + BUFF_SZ)) {
// ザイズが仕様の範囲外
LOG_ERR("Invalid content_length: %d", http_res.content_length);
return -1;
}
if (sipf_obj_head[0] != OBJECTS_DOWN) {
// OBJECTS_DOWNじゃない
LOG_ERR("Invalid command type: %d", sipf_obj_head[0]);
return -1;
}

if (sipf_obj_payload[0] != 0x00) {
// REQEST_RESULTがOK(0x00)じゃない
LOG_ERR("REQUEST_RESULT: %d", sipf_obj_payload[0]);
return -1;
}

// OTIDをコピー
memcpy(&otid->value, &sipf_obj_payload[1], sizeof(otid->value));
// USER_SEND_DATETIME_MSへのポインタをコピー
*p_user_send_datetime = &sipf_obj_payload[17];
// RECEIVED_DATETIME_MSへのポインタをコピー
*p_recv_datetime = &sipf_obj_payload[25];
// REMAINS
*remains = sipf_obj_payload[33];
// (RESERVED)

// obj
*objqty = 0;
if (http_res.content_length == 12 + 35) {
// objなし
LOG_INF("empty");
return 0;
}
int idx = 35; // objの先頭
for (;;) {
//オブジェクトの先頭ポインタをリストに追加
p_objs[(*objqty)++] = &sipf_obj_payload[idx];
//オブジェクト数の上限に達してたら中断
if (*objqty >= 16) {
break;
}
//インデックスを次のオブジェクトの先頭に設定
idx += (3 + sipf_obj_payload[idx + 2]);
if (idx >= http_res.content_length - 12) {
//インデックスが受信データの終端を超えた
break;
}
}

return 0;
}
27 changes: 27 additions & 0 deletions src/sipf/sipf_object.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "sipf/sipf_object.h"

/**
* Byte列をパースして構造体に詰めるよ
*/
int SipfObjectParse(uint8_t *raw_buff, const uint16_t raw_len, SipfObjectObject *obj)
{
if (raw_buff == NULL) {
return -1;
}
if (obj == NULL) {
return -1;
}
if (obj->value == NULL) {
return -1;
}
if ((raw_len < 4) || (raw_len > 256)) {
return -1;
}
//バッファから構造体へ
obj->obj_type = raw_buff[0];
obj->obj_tagid = raw_buff[1];
obj->value_len = raw_buff[2];
memcpy(obj->value, &raw_buff[3], obj->value_len);

return 0;
}

0 comments on commit b1934d8

Please sign in to comment.