IS2: Go to protobuf v3
This commit is contained in:
parent
5eee1b66d3
commit
1dfba6333a
161
src/aprsis2.c
161
src/aprsis2.c
|
|
@ -61,11 +61,11 @@ static void *is2_allocate_buffer(int len)
|
|||
* Write a message to a client, return result from c->write
|
||||
*/
|
||||
|
||||
static int is2_write_message(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
static int is2_write_message(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
char buf[IS2_MAXIMUM_FRAME_LEN];
|
||||
|
||||
int len = is2_message__get_packed_size(m);
|
||||
int len = aprsis2__is2_message__get_packed_size(m);
|
||||
int blen = len + IS2_HEAD_LEN + IS2_TAIL_LEN;
|
||||
|
||||
if (blen > IS2_MAXIMUM_FRAME_LEN) {
|
||||
|
|
@ -75,7 +75,7 @@ static int is2_write_message(struct worker_t *self, struct client_t *c, IS2Messa
|
|||
|
||||
//hlog(LOG_DEBUG, "%s/%s: IS2: serialized length %d", c->addr_rem, c->username, len);
|
||||
is2_setup_buffer(buf, len);
|
||||
is2_message__pack(m, (void *)buf + IS2_HEAD_LEN);
|
||||
aprsis2__is2_message__pack(m, (void *)buf + IS2_HEAD_LEN);
|
||||
|
||||
return c->write(self, c, buf, blen);
|
||||
}
|
||||
|
|
@ -84,12 +84,12 @@ static int is2_write_message(struct worker_t *self, struct client_t *c, IS2Messa
|
|||
* Write an UDP message to a client, return result from c->write
|
||||
*/
|
||||
|
||||
static int is2_corepeer_write_message(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
static int is2_corepeer_write_message(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
m->sequence = c->corepeer_is2_sequence++;
|
||||
m->has_sequence = 1;
|
||||
|
||||
int len = is2_message__get_packed_size(m);
|
||||
int len = aprsis2__is2_message__get_packed_size(m);
|
||||
int blen = len + IS2_HEAD_LEN + IS2_TAIL_LEN;
|
||||
if (blen > c->obuf_size) {
|
||||
hlog(LOG_DEBUG, "%s/%s: IS2 UDP: serialized IS2 frame length %d does not fit in obuf", c->addr_rem, c->username, blen);
|
||||
|
|
@ -97,7 +97,7 @@ static int is2_corepeer_write_message(struct worker_t *self, struct client_t *c,
|
|||
}
|
||||
is2_setup_buffer(c->obuf, len);
|
||||
|
||||
is2_message__pack(m, (void *)c->obuf + IS2_HEAD_LEN);
|
||||
aprsis2__is2_message__pack(m, (void *)c->obuf + IS2_HEAD_LEN);
|
||||
int r = udp_client_write(self, c, c->obuf, blen);
|
||||
hlog(LOG_DEBUG, "%s/%s: IS2 UDP: serialized length %d, frame %d, wrote %d", c->addr_rem, c->username, len, len + IS2_HEAD_LEN + IS2_TAIL_LEN, r);
|
||||
|
||||
|
|
@ -110,15 +110,16 @@ static int is2_corepeer_write_message(struct worker_t *self, struct client_t *c,
|
|||
|
||||
int is2_out_server_signature(struct worker_t *self, struct client_t *c)
|
||||
{
|
||||
IS2ServerSignature sig = IS2_SERVER_SIGNATURE__INIT;
|
||||
Aprsis2__IS2ServerSignature sig = APRSIS2__IS2_SERVER_SIGNATURE__INIT;
|
||||
sig.username = serverid;
|
||||
sig.app_name = verstr_progname;
|
||||
sig.app_version = version_build;
|
||||
sig.n_features = 0;
|
||||
sig.features = NULL;
|
||||
|
||||
IS2Message m = IS2_MESSAGE__INIT;
|
||||
m.type = IS2_MESSAGE__TYPE__SERVER_SIGNATURE;
|
||||
Aprsis2__IS2Message m = APRSIS2__IS2_MESSAGE__INIT;
|
||||
m.has_type = 1;
|
||||
m.type = APRSIS2__IS2_MESSAGE__TYPE__SERVER_SIGNATURE;
|
||||
m.server_signature = &sig;
|
||||
|
||||
return is2_write_message(self, c, &m);
|
||||
|
|
@ -128,15 +129,19 @@ int is2_out_server_signature(struct worker_t *self, struct client_t *c)
|
|||
* Transmit a login reply to a new client
|
||||
*/
|
||||
|
||||
int is2_out_login_reply(struct worker_t *self, struct client_t *c, IS2LoginReply__LoginResult result, IS2LoginReply__LoginResultReason reason, VerificationStatus verified)
|
||||
int is2_out_login_reply(struct worker_t *self, struct client_t *c, Aprsis2__IS2LoginReply__LoginResult result, Aprsis2__IS2LoginReply__LoginResultReason reason, Aprsis2__VerificationStatus verified)
|
||||
{
|
||||
IS2LoginReply lr = IS2_LOGIN_REPLY__INIT;
|
||||
Aprsis2__IS2LoginReply lr = APRSIS2__IS2_LOGIN_REPLY__INIT;
|
||||
lr.has_result = 1;
|
||||
lr.has_result_code = 1;
|
||||
lr.has_verified = 1;
|
||||
lr.result = result;
|
||||
lr.result_code = reason;
|
||||
lr.verified = verified;
|
||||
|
||||
IS2Message m = IS2_MESSAGE__INIT;
|
||||
m.type = IS2_MESSAGE__TYPE__LOGIN_REPLY;
|
||||
Aprsis2__IS2Message m = APRSIS2__IS2_MESSAGE__INIT;
|
||||
m.has_type = 1;
|
||||
m.type = APRSIS2__IS2_MESSAGE__TYPE__LOGIN_REPLY;
|
||||
m.login_reply = &lr;
|
||||
|
||||
return is2_write_message(self, c, &m);
|
||||
|
|
@ -146,16 +151,16 @@ int is2_out_login_reply(struct worker_t *self, struct client_t *c, IS2LoginReply
|
|||
* Receive a login reply
|
||||
*/
|
||||
|
||||
static int is2_in_login_reply(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
static int is2_in_login_reply(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
IS2LoginReply *lr = m->login_reply;
|
||||
Aprsis2__IS2LoginReply *lr = m->login_reply;
|
||||
if (!lr) {
|
||||
hlog(LOG_WARNING, "%s/%s: IS2: unpacking of login reply failed",
|
||||
c->addr_rem, c->username);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lr->result != IS2_LOGIN_REPLY__LOGIN_RESULT__OK) {
|
||||
if (lr->result != APRSIS2__IS2_LOGIN_REPLY__LOGIN_RESULT__OK) {
|
||||
hlog(LOG_INFO, "%s/%s: IS2: Login failed: '%s' (%d)",
|
||||
c->addr_rem, c->username,
|
||||
(lr->result_message) ? lr->result_message : "no reason", lr->result_code);
|
||||
|
|
@ -180,9 +185,9 @@ static int is2_in_login_reply(struct worker_t *self, struct client_t *c, IS2Mess
|
|||
* - if ok, continue by sending a login command
|
||||
*/
|
||||
|
||||
static int is2_in_server_signature(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
static int is2_in_server_signature(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
IS2ServerSignature *sig = m->server_signature;
|
||||
Aprsis2__IS2ServerSignature *sig = m->server_signature;
|
||||
if (!sig) {
|
||||
hlog(LOG_WARNING, "%s/%s: IS2: unpacking of server signature failed",
|
||||
c->addr_rem, c->username);
|
||||
|
|
@ -219,15 +224,16 @@ static int is2_in_server_signature(struct worker_t *self, struct client_t *c, IS
|
|||
#endif
|
||||
|
||||
/* Ok, we're happy with the uplink's server signature, let us login! */
|
||||
IS2LoginRequest lr = IS2_LOGIN_REQUEST__INIT;
|
||||
Aprsis2__IS2LoginRequest lr = APRSIS2__IS2_LOGIN_REQUEST__INIT;
|
||||
lr.username = serverid;
|
||||
lr.app_name = verstr_progname;
|
||||
lr.app_version = version_build;
|
||||
lr.n_features_req = 0;
|
||||
lr.features_req = NULL;
|
||||
|
||||
IS2Message mr = IS2_MESSAGE__INIT;
|
||||
mr.type = IS2_MESSAGE__TYPE__LOGIN_REQUEST;
|
||||
Aprsis2__IS2Message mr = APRSIS2__IS2_MESSAGE__INIT;
|
||||
mr.has_type = 1;
|
||||
mr.type = APRSIS2__IS2_MESSAGE__TYPE__LOGIN_REQUEST;
|
||||
mr.login_request = &lr;
|
||||
|
||||
is2_write_message(self, c, &mr);
|
||||
|
|
@ -272,11 +278,11 @@ static int is2_login_client_validate_cert(struct worker_t *self, struct client_t
|
|||
* Incoming login request
|
||||
*/
|
||||
|
||||
static int is2_in_login_request(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
static int is2_in_login_request(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
IS2LoginRequest *lr = m->login_request;
|
||||
Aprsis2__IS2LoginRequest *lr = m->login_request;
|
||||
if (!lr) {
|
||||
hlog(LOG_WARNING, "%s/%s: IS2: unpacking of login request failed",
|
||||
c->addr_rem, c->username);
|
||||
|
|
@ -381,20 +387,20 @@ static int is2_in_login_request(struct worker_t *self, struct client_t *c, IS2Me
|
|||
(*c->app_version) ? c->app_version : ""
|
||||
);
|
||||
|
||||
VerificationStatus vs;
|
||||
Aprsis2__VerificationStatus vs;
|
||||
switch (c->validated) {
|
||||
case VALIDATED_WEAK:
|
||||
vs = VERIFICATION_STATUS__WEAK;
|
||||
vs = APRSIS2__VERIFICATION_STATUS__WEAK;
|
||||
break;
|
||||
case VALIDATED_STRONG:
|
||||
vs = VERIFICATION_STATUS__WEAK;
|
||||
vs = APRSIS2__VERIFICATION_STATUS__STRONG;
|
||||
break;
|
||||
default:
|
||||
vs = VERIFICATION_STATUS__NONE;
|
||||
vs = APRSIS2__VERIFICATION_STATUS__NONE;
|
||||
}
|
||||
|
||||
/* tell the client he's good */
|
||||
is2_out_login_reply(self, c, IS2_LOGIN_REPLY__LOGIN_RESULT__OK, IS2_LOGIN_REPLY__LOGIN_RESULT_REASON__NONE, vs);
|
||||
is2_out_login_reply(self, c, APRSIS2__IS2_LOGIN_REPLY__LOGIN_RESULT__OK, APRSIS2__IS2_LOGIN_REPLY__LOGIN_RESULT_REASON__NONE, vs);
|
||||
|
||||
/* mark as connected and classify */
|
||||
worker_mark_client_connected(self, c);
|
||||
|
|
@ -443,11 +449,11 @@ failed_login:
|
|||
* Incoming packet handler
|
||||
*/
|
||||
|
||||
static int is2_in_packet(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
static int is2_in_packet(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
int i;
|
||||
int r = 0;
|
||||
ISPacket *p;
|
||||
Aprsis2__ISPacket *p;
|
||||
|
||||
//hlog(LOG_DEBUG, "%s/%s: IS2: %d packets received in message", c->addr_rem, c->username, m->n_is_packet);
|
||||
|
||||
|
|
@ -456,7 +462,7 @@ static int is2_in_packet(struct worker_t *self, struct client_t *c, IS2Message *
|
|||
|
||||
//hlog(LOG_DEBUG, "%s/%s: IS2: packet type %d len %d", c->addr_rem, c->username, p->type, p->is_packet_data.len);
|
||||
|
||||
if (p->type == ISPACKET__TYPE__IS_PACKET && p->has_is_packet_data) {
|
||||
if (p->type == APRSIS2__ISPACKET__TYPE__IS_PACKET && p->has_is_packet_data) {
|
||||
incoming_handler(self, c, IPPROTO_TCP, (char *)p->is_packet_data.data, p->is_packet_data.len);
|
||||
}
|
||||
}
|
||||
|
|
@ -490,14 +496,17 @@ int is2_out_ping(struct worker_t *self, struct client_t *c)
|
|||
|
||||
c->ping_timeout = tick + IS2_PING_TIMEOUT;
|
||||
|
||||
IS2KeepalivePing ping = IS2_KEEPALIVE_PING__INIT;
|
||||
ping.ping_type = IS2_KEEPALIVE_PING__PING_TYPE__REQUEST;
|
||||
Aprsis2__IS2KeepalivePing ping = APRSIS2__IS2_KEEPALIVE_PING__INIT;
|
||||
ping.ping_type = APRSIS2__IS2_KEEPALIVE_PING__PING_TYPE__REQUEST;
|
||||
ping.has_ping_type = 1;
|
||||
ping.request_id = c->ping_request_id = random();
|
||||
ping.has_request_id = 1;
|
||||
ping.request_data = rdata;
|
||||
ping.has_request_data = 1;
|
||||
|
||||
IS2Message m = IS2_MESSAGE__INIT;
|
||||
m.type = IS2_MESSAGE__TYPE__KEEPALIVE_PING;
|
||||
Aprsis2__IS2Message m = APRSIS2__IS2_MESSAGE__INIT;
|
||||
m.has_type = 1;
|
||||
m.type = APRSIS2__IS2_MESSAGE__TYPE__KEEPALIVE_PING;
|
||||
m.keepalive_ping = &ping;
|
||||
|
||||
return is2_write_message(self, c, &m);
|
||||
|
|
@ -507,11 +516,11 @@ int is2_out_ping(struct worker_t *self, struct client_t *c)
|
|||
* Incoming ping handler, responds with a reply when a request is received
|
||||
*/
|
||||
|
||||
static int is2_in_ping(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
static int is2_in_ping(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
IS2KeepalivePing *ping = m->keepalive_ping;
|
||||
Aprsis2__IS2KeepalivePing *ping = m->keepalive_ping;
|
||||
if (!ping) {
|
||||
hlog(LOG_WARNING, "%s/%s: IS2: unpacking of ping failed",
|
||||
c->addr_rem, c->username);
|
||||
|
|
@ -521,16 +530,16 @@ static int is2_in_ping(struct worker_t *self, struct client_t *c, IS2Message *m)
|
|||
|
||||
hlog(LOG_DEBUG, "%s/%s: IS2: Ping %s received: request_id %lu",
|
||||
c->addr_rem, c->username,
|
||||
(ping->ping_type == IS2_KEEPALIVE_PING__PING_TYPE__REQUEST) ? "request" : "reply",
|
||||
(ping->ping_type == APRSIS2__IS2_KEEPALIVE_PING__PING_TYPE__REQUEST) ? "request" : "reply",
|
||||
ping->request_id);
|
||||
|
||||
if (ping->ping_type == IS2_KEEPALIVE_PING__PING_TYPE__REQUEST) {
|
||||
ping->ping_type = IS2_KEEPALIVE_PING__PING_TYPE__REPLY;
|
||||
if (ping->ping_type == APRSIS2__IS2_KEEPALIVE_PING__PING_TYPE__REQUEST) {
|
||||
ping->ping_type = APRSIS2__IS2_KEEPALIVE_PING__PING_TYPE__REPLY;
|
||||
|
||||
r = is2_write_message(self, c, m);
|
||||
}
|
||||
|
||||
if (ping->ping_type == IS2_KEEPALIVE_PING__PING_TYPE__REPLY && ping->request_id == c->ping_request_id) {
|
||||
if (ping->ping_type == APRSIS2__IS2_KEEPALIVE_PING__PING_TYPE__REPLY && ping->request_id == c->ping_request_id) {
|
||||
double diff;
|
||||
#ifdef USE_CLOCK_GETTIME
|
||||
struct timespec ts;
|
||||
|
|
@ -578,11 +587,11 @@ done:
|
|||
* Incoming parameter set handler
|
||||
*/
|
||||
|
||||
static int is2_in_parameter(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
static int is2_in_parameter(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
IS2Parameter *par = m->parameter;
|
||||
Aprsis2__IS2Parameter *par = m->parameter;
|
||||
if (!par) {
|
||||
hlog(LOG_WARNING, "%s/%s: IS2: unpacking of parameter message failed: no parameter payload",
|
||||
c->addr_rem, c->username);
|
||||
|
|
@ -590,7 +599,7 @@ static int is2_in_parameter(struct worker_t *self, struct client_t *c, IS2Messag
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (par->type != IS2_PARAMETER__TYPE__PARAMETER_SET) {
|
||||
if (par->type != APRSIS2__IS2_PARAMETER__TYPE__PARAMETER_SET) {
|
||||
hlog(LOG_WARNING, "%s/%s: IS2: unpacking of parameter message failed: wrong type %d (not PARAMETER_SET)",
|
||||
c->addr_rem, c->username, par->type);
|
||||
r = -1;
|
||||
|
|
@ -602,19 +611,21 @@ static int is2_in_parameter(struct worker_t *self, struct client_t *c, IS2Messag
|
|||
(par->filter_string) ? " filter_string" : "");
|
||||
|
||||
/* prepare reply message */
|
||||
IS2Parameter prep = IS2_PARAMETER__INIT;
|
||||
prep.type = IS2_PARAMETER__TYPE__PARAMETER_FAILED;
|
||||
Aprsis2__IS2Parameter prep = APRSIS2__IS2_PARAMETER__INIT;
|
||||
prep.has_type = 1;
|
||||
prep.type = APRSIS2__IS2_PARAMETER__TYPE__PARAMETER_FAILED;
|
||||
prep.has_request_id = par->has_request_id;
|
||||
if (prep.has_request_id)
|
||||
prep.request_id = par->request_id;
|
||||
IS2Message rm = IS2_MESSAGE__INIT;
|
||||
rm.type = IS2_MESSAGE__TYPE__PARAMETER;
|
||||
Aprsis2__IS2Message rm = APRSIS2__IS2_MESSAGE__INIT;
|
||||
rm.has_type = 1;
|
||||
rm.type = APRSIS2__IS2_MESSAGE__TYPE__PARAMETER;
|
||||
rm.parameter = &prep;
|
||||
|
||||
if (par->filter_string) {
|
||||
filter_set(c, par->filter_string, strlen(par->filter_string));
|
||||
|
||||
prep.type = IS2_PARAMETER__TYPE__PARAMETER_APPLIED;
|
||||
prep.type = APRSIS2__IS2_PARAMETER__TYPE__PARAMETER_APPLIED;
|
||||
prep.filter_string = c->filter_s;
|
||||
} else {
|
||||
hlog(LOG_WARNING, "%s/%s: IS2: PARAMETER_SET: No parameters found for setting",
|
||||
|
|
@ -632,14 +643,14 @@ done:
|
|||
* transmit a server signature
|
||||
*/
|
||||
|
||||
int is2_input_handler_uplink_wait_signature(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
int is2_input_handler_uplink_wait_signature(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
switch (m->type) {
|
||||
case IS2_MESSAGE__TYPE__SERVER_SIGNATURE:
|
||||
case APRSIS2__IS2_MESSAGE__TYPE__SERVER_SIGNATURE:
|
||||
return is2_in_server_signature(self, c, m);
|
||||
case IS2_MESSAGE__TYPE__KEEPALIVE_PING:
|
||||
case APRSIS2__IS2_MESSAGE__TYPE__KEEPALIVE_PING:
|
||||
return is2_in_ping(self, c, m);
|
||||
case IS2_MESSAGE__TYPE__LOGIN_REPLY:
|
||||
case APRSIS2__IS2_MESSAGE__TYPE__LOGIN_REPLY:
|
||||
return is2_in_login_reply(self, c, m);
|
||||
default:
|
||||
hlog(LOG_WARNING, "%s/%s: IS2: connect: unknown message type %d",
|
||||
|
|
@ -654,13 +665,13 @@ int is2_input_handler_uplink_wait_signature(struct worker_t *self, struct client
|
|||
* IS2 input handler, when waiting for a login command
|
||||
*/
|
||||
|
||||
int is2_input_handler_login(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
int is2_input_handler_login(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
switch (m->type) {
|
||||
case IS2_MESSAGE__TYPE__KEEPALIVE_PING:
|
||||
case APRSIS2__IS2_MESSAGE__TYPE__KEEPALIVE_PING:
|
||||
return is2_in_ping(self, c, m);
|
||||
break;
|
||||
case IS2_MESSAGE__TYPE__LOGIN_REQUEST:
|
||||
case APRSIS2__IS2_MESSAGE__TYPE__LOGIN_REQUEST:
|
||||
return is2_in_login_request(self, c, m);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -676,16 +687,16 @@ int is2_input_handler_login(struct worker_t *self, struct client_t *c, IS2Messag
|
|||
* IS2 input handler, connected state
|
||||
*/
|
||||
|
||||
int is2_input_handler(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
int is2_input_handler(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
switch (m->type) {
|
||||
case IS2_MESSAGE__TYPE__KEEPALIVE_PING:
|
||||
case APRSIS2__IS2_MESSAGE__TYPE__KEEPALIVE_PING:
|
||||
return is2_in_ping(self, c, m);
|
||||
break;
|
||||
case IS2_MESSAGE__TYPE__PARAMETER:
|
||||
case APRSIS2__IS2_MESSAGE__TYPE__PARAMETER:
|
||||
return is2_in_parameter(self, c, m);
|
||||
break;
|
||||
case IS2_MESSAGE__TYPE__IS_PACKET:
|
||||
case APRSIS2__IS2_MESSAGE__TYPE__IS_PACKET:
|
||||
return is2_in_packet(self, c, m);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -701,13 +712,13 @@ int is2_input_handler(struct worker_t *self, struct client_t *c, IS2Message *m)
|
|||
* IS2 input handler, corepeer state
|
||||
*/
|
||||
|
||||
int is2_input_handler_corepeer(struct worker_t *self, struct client_t *c, IS2Message *m)
|
||||
int is2_input_handler_corepeer(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m)
|
||||
{
|
||||
switch (m->type) {
|
||||
case IS2_MESSAGE__TYPE__KEEPALIVE_PING:
|
||||
case APRSIS2__IS2_MESSAGE__TYPE__KEEPALIVE_PING:
|
||||
return is2_in_ping(self, c, m);
|
||||
break;
|
||||
case IS2_MESSAGE__TYPE__IS_PACKET:
|
||||
case APRSIS2__IS2_MESSAGE__TYPE__IS_PACKET:
|
||||
return is2_in_packet(self, c, m);
|
||||
break;
|
||||
default:
|
||||
|
|
@ -725,7 +736,7 @@ int is2_input_handler_corepeer(struct worker_t *self, struct client_t *c, IS2Mes
|
|||
|
||||
static int is2_unpack_message(struct worker_t *self, struct client_t *c, void *buf, int len)
|
||||
{
|
||||
IS2Message *m = is2_message__unpack(NULL, len, buf);
|
||||
Aprsis2__IS2Message *m = aprsis2__is2_message__unpack(NULL, len, buf);
|
||||
if (!m) {
|
||||
hlog_packet(LOG_WARNING, buf, len, "%s/%s: IS2: unpacking of message failed: ",
|
||||
c->addr_rem, c->username);
|
||||
|
|
@ -735,7 +746,7 @@ static int is2_unpack_message(struct worker_t *self, struct client_t *c, void *b
|
|||
/* Call the current input message handler */
|
||||
int r = c->is2_input_handler(self, c, m);
|
||||
|
||||
is2_message__free_unpacked(m, NULL);
|
||||
aprsis2__is2_message__free_unpacked(m, NULL);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
@ -845,31 +856,33 @@ int is2_corepeer_deframe_input(struct worker_t *self, struct client_t *c, char *
|
|||
* OPTIMIZE: generate packet once, or reuse incoming prepacked buffer
|
||||
*/
|
||||
|
||||
static int is2_encode_packet(IS2Message *m, ProtobufCBinaryData *data, char *p, int len)
|
||||
static int is2_encode_packet(Aprsis2__IS2Message *m, ProtobufCBinaryData *data, char *p, int len)
|
||||
{
|
||||
data->data = (uint8_t *)p;
|
||||
data->len = len;
|
||||
|
||||
int n = 1; // just one packet
|
||||
int i;
|
||||
ISPacket **subs = hmalloc(sizeof(ISPacket*) * n);
|
||||
Aprsis2__ISPacket **subs = hmalloc(sizeof(Aprsis2__ISPacket*) * n);
|
||||
for (i = 0; i < n; i++) {
|
||||
//hlog(LOG_DEBUG, "packing packet %d", i);
|
||||
subs[i] = hmalloc(sizeof(ISPacket));
|
||||
ispacket__init(subs[i]);
|
||||
subs[i]->type = ISPACKET__TYPE__IS_PACKET;
|
||||
subs[i] = hmalloc(sizeof(Aprsis2__ISPacket));
|
||||
aprsis2__ispacket__init(subs[i]);
|
||||
subs[i]->has_type = 1;
|
||||
subs[i]->type = APRSIS2__ISPACKET__TYPE__IS_PACKET;
|
||||
subs[i]->has_is_packet_data = 1;
|
||||
subs[i]->is_packet_data = *data;
|
||||
}
|
||||
|
||||
m->type = IS2_MESSAGE__TYPE__IS_PACKET;
|
||||
m->has_type = 1;
|
||||
m->type = APRSIS2__IS2_MESSAGE__TYPE__IS_PACKET;
|
||||
m->n_is_packet = n;
|
||||
m->is_packet = subs;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void is2_free_encoded_packets(IS2Message *m)
|
||||
void is2_free_encoded_packets(Aprsis2__IS2Message *m)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
@ -886,7 +899,7 @@ int is2_write_packet(struct worker_t *self, struct client_t *c, char *p, int len
|
|||
|
||||
//hlog(LOG_DEBUG, "%s/%s: IS2: writing IS packet of %d bytes", c->addr_rem, c->username, len);
|
||||
|
||||
IS2Message m = IS2_MESSAGE__INIT;
|
||||
Aprsis2__IS2Message m = APRSIS2__IS2_MESSAGE__INIT;
|
||||
ProtobufCBinaryData data;
|
||||
is2_encode_packet(&m, &data, p, len);
|
||||
|
||||
|
|
@ -910,7 +923,7 @@ int is2_corepeer_write_packet(struct worker_t *self, struct client_t *c, char *p
|
|||
|
||||
//hlog(LOG_DEBUG, "%s/%s: IS2: writing IS packet of %d bytes", c->addr_rem, c->username, len);
|
||||
|
||||
IS2Message m = IS2_MESSAGE__INIT;
|
||||
Aprsis2__IS2Message m = APRSIS2__IS2_MESSAGE__INIT;
|
||||
ProtobufCBinaryData data;
|
||||
is2_encode_packet(&m, &data, p, len);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@
|
|||
|
||||
#include "worker.h"
|
||||
|
||||
extern int is2_input_handler_login(struct worker_t *self, struct client_t *c, IS2Message *m);
|
||||
extern int is2_input_handler_uplink_wait_signature(struct worker_t *self, struct client_t *c, IS2Message *m);
|
||||
extern int is2_input_handler(struct worker_t *self, struct client_t *c, IS2Message *m);
|
||||
extern int is2_input_handler_login(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m);
|
||||
extern int is2_input_handler_uplink_wait_signature(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m);
|
||||
extern int is2_input_handler(struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *m);
|
||||
|
||||
extern int is2_out_server_signature(struct worker_t *self, struct client_t *c);
|
||||
extern int is2_deframe_input(struct worker_t *self, struct client_t *c, int start_at);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
syntax = "proto2";
|
||||
syntax = "proto3";
|
||||
|
||||
package aprsis2;
|
||||
|
||||
//
|
||||
// A server sends an IS2ServerSignature to all new clients.
|
||||
|
|
@ -9,9 +11,9 @@ syntax = "proto2";
|
|||
//
|
||||
|
||||
message IS2ServerSignature {
|
||||
required string username = 1; // callsign-SSID
|
||||
required string app_name = 2;
|
||||
required string app_version = 3;
|
||||
string username = 1; // callsign-SSID
|
||||
string app_name = 2;
|
||||
string app_version = 3;
|
||||
repeated string features = 4; // list of supported optional features
|
||||
}
|
||||
|
||||
|
|
@ -24,10 +26,10 @@ message IS2ServerSignature {
|
|||
//
|
||||
|
||||
message IS2LoginRequest {
|
||||
required string username = 1; // callsign-SSID
|
||||
optional string password = 2; // passcode or password
|
||||
required string app_name = 3;
|
||||
required string app_version = 4;
|
||||
string username = 1; // callsign-SSID
|
||||
string password = 2; // passcode or password
|
||||
string app_name = 3;
|
||||
string app_version = 4;
|
||||
// 5: unused
|
||||
repeated string features_req = 6; // list of requested optional features
|
||||
}
|
||||
|
|
@ -83,10 +85,10 @@ message IS2LoginReply {
|
|||
CERT_EXPIRED = 5;
|
||||
}
|
||||
|
||||
required LoginResult result = 1;
|
||||
required VerificationStatus verified = 2;
|
||||
optional LoginResultReason result_code = 3;
|
||||
optional string result_message = 4; // english descriptive
|
||||
LoginResult result = 1;
|
||||
VerificationStatus verified = 2;
|
||||
LoginResultReason result_code = 3;
|
||||
string result_message = 4; // english descriptive
|
||||
repeated string features_ack = 5; // list of agreed optional features
|
||||
}
|
||||
|
||||
|
|
@ -105,13 +107,14 @@ message IS2LoginReply {
|
|||
|
||||
message IS2KeepalivePing {
|
||||
enum PingType {
|
||||
UNDEFINED = 0;
|
||||
REQUEST = 1;
|
||||
REPLY = 2;
|
||||
}
|
||||
|
||||
required PingType ping_type = 1;
|
||||
required uint32 request_id = 2;
|
||||
optional bytes request_data = 3;
|
||||
PingType ping_type = 1;
|
||||
uint32 request_id = 2;
|
||||
bytes request_data = 3;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -120,15 +123,16 @@ message IS2KeepalivePing {
|
|||
|
||||
message ISPacket {
|
||||
enum Type {
|
||||
UNDEFINED = 0;
|
||||
// Traditional APRS-IS format with embedded Q construct
|
||||
IS_PACKET = 2;
|
||||
}
|
||||
|
||||
// Identifies which message is filled in.
|
||||
required Type type = 1;
|
||||
Type type = 1;
|
||||
|
||||
// packet data in traditional APRS-IS format, without CRLF
|
||||
optional bytes is_packet_data = 2;
|
||||
bytes is_packet_data = 2;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -156,16 +160,17 @@ message ISPacket {
|
|||
|
||||
message IS2Parameter {
|
||||
enum Type {
|
||||
PARAMETER_UNDEFINED = 0;
|
||||
PARAMETER_CURRENT = 1; // this is the current value of the parameter
|
||||
PARAMETER_SET = 2; // set a parameter to this value
|
||||
PARAMETER_APPLIED = 3; // parameter has been set successfully
|
||||
PARAMETER_FAILED = 4; // parameter change failed
|
||||
}
|
||||
|
||||
required Type type = 1;
|
||||
optional int32 request_id = 2;
|
||||
Type type = 1;
|
||||
int32 request_id = 2;
|
||||
|
||||
optional string filter_string = 3;
|
||||
string filter_string = 3;
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -180,6 +185,7 @@ message IS2Parameter {
|
|||
|
||||
message IS2Message {
|
||||
enum Type {
|
||||
UNDEFINED = 0;
|
||||
SERVER_SIGNATURE = 2;
|
||||
LOGIN_REQUEST = 3;
|
||||
LOGIN_REPLY = 4;
|
||||
|
|
@ -189,19 +195,19 @@ message IS2Message {
|
|||
}
|
||||
|
||||
// Identifies which message is filled in.
|
||||
required Type type = 1;
|
||||
Type type = 1;
|
||||
|
||||
// For UDP packets, a sequence number may be transmitted
|
||||
optional uint32 sequence = 2;
|
||||
uint32 sequence = 2;
|
||||
// For UDP packets, a HMAC signature may be transmitted
|
||||
optional bytes signature = 3;
|
||||
bytes signature = 3;
|
||||
|
||||
// One of the following will be filled in. Just one.
|
||||
optional IS2ServerSignature server_signature = 21;
|
||||
optional IS2LoginRequest login_request = 22;
|
||||
optional IS2LoginReply login_reply = 23;
|
||||
optional IS2KeepalivePing keepalive_ping = 24;
|
||||
IS2ServerSignature server_signature = 21;
|
||||
IS2LoginRequest login_request = 22;
|
||||
IS2LoginReply login_reply = 23;
|
||||
IS2KeepalivePing keepalive_ping = 24;
|
||||
repeated ISPacket is_packet = 25;
|
||||
optional IS2Parameter parameter = 26;
|
||||
IS2Parameter parameter = 26;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ struct client_t {
|
|||
|
||||
/* the current handler function for incoming lines */
|
||||
int (*handler_line_in) (struct worker_t *self, struct client_t *c, int l4proto, char *s, int len);
|
||||
int (*is2_input_handler) (struct worker_t *self, struct client_t *c, IS2Message *message);
|
||||
int (*is2_input_handler) (struct worker_t *self, struct client_t *c, Aprsis2__IS2Message *message);
|
||||
int (*handler_consume_input) (struct worker_t *self, struct client_t *c, int start_at);
|
||||
int (*write) (struct worker_t *self, struct client_t *c, char *p, int len);
|
||||
int (*write_packet) (struct worker_t *self, struct client_t *c, char *p, int len);
|
||||
|
|
|
|||
|
|
@ -11,9 +11,11 @@ use IO::Socket::INET;
|
|||
use IO::Select;
|
||||
use Data::Dumper;
|
||||
|
||||
use Google::ProtocolBuffers;
|
||||
use Google::ProtocolBuffers::Dynamic;
|
||||
|
||||
Google::ProtocolBuffers->parsefile("../src/aprsis2.proto", { create_accessors => 1 });
|
||||
my $pf = Google::ProtocolBuffers::Dynamic->new("../src");
|
||||
$pf->load_file("aprsis2.proto");
|
||||
$pf->map({package => "aprsis2", prefix => "APRSIS2"});
|
||||
|
||||
our $VERSION = '0.01';
|
||||
|
||||
|
|
@ -184,15 +186,15 @@ sub connect($;%)
|
|||
}
|
||||
|
||||
# send login request
|
||||
my $lm = IS2LoginRequest->new({
|
||||
my $lm = APRSIS2::IS2LoginRequest->new({
|
||||
'username' => $self->{'mycall'},
|
||||
'password' => $self->{'aprspass'},
|
||||
'app_name' => $aprs_appname,
|
||||
'app_version' => $VERSION
|
||||
});
|
||||
|
||||
my $im = IS2Message->new({
|
||||
'type' => IS2Message::Type::LOGIN_REQUEST(),
|
||||
my $im = APRSIS2::IS2Message->new({
|
||||
'type' => APRSIS2::IS2Message::Type::LOGIN_REQUEST(),
|
||||
'login_request' => $lm
|
||||
});
|
||||
|
||||
|
|
@ -200,8 +202,8 @@ sub connect($;%)
|
|||
|
||||
my $t = time();
|
||||
while (my $l = $self->is2_frame_in()) {
|
||||
my $rep = $l->login_reply;
|
||||
if ($l->type == IS2Message::Type::LOGIN_REPLY()) {
|
||||
if ($l->get_type() == APRSIS2::IS2Message::Type::LOGIN_REPLY()) {
|
||||
my $rep = $l->get_login_reply();
|
||||
if (!$rep) {
|
||||
$self->{'error'} = "LOGIN_REPLY type, but no login_reply message";
|
||||
return 0;
|
||||
|
|
@ -212,18 +214,18 @@ sub connect($;%)
|
|||
# defined $rep->result_code ? $rep->result_code : 0,
|
||||
# defined $rep->result_message ? $rep->result_message : '');
|
||||
|
||||
if ($rep->result != IS2LoginReply::LoginResult::OK()) {
|
||||
if ($rep->get_result() != APRSIS2::IS2LoginReply::LoginResult::OK()) {
|
||||
$self->{'error'} = sprintf("Login reply: login failed, code %d: %s",
|
||||
defined $rep->result_code ? $rep->result_code : 0,
|
||||
defined $rep->result_message ? $rep->result_message : '');
|
||||
defined $rep->get_result_code() ? $rep->get_result_code() : 0,
|
||||
defined $rep->get_result_message() ? $rep->get_result_message() : '');
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($self->{'aprspass'} != -1 && $rep->verified < 1) {
|
||||
if ($self->{'aprspass'} != -1 && $rep->get_verified() < 1) {
|
||||
$self->{'error'} = sprintf("Login reply: login not verified (%d), code %d: %s",
|
||||
$rep->verified,
|
||||
defined $rep->result_code ? $rep->result_code : 0,
|
||||
defined $rep->result_message ? $rep->result_message : '');
|
||||
$rep->get_verified(),
|
||||
defined $rep->get_result_code() ? $rep->get_result_code() : 0,
|
||||
defined $rep->get_result_message() ? $rep->get_result_message() : '');
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -253,14 +255,14 @@ sub send_packets($$)
|
|||
|
||||
my @pq;
|
||||
foreach my $p (@{ $packets }) {
|
||||
push @pq, ISPacket->new({
|
||||
'type' => ISPacket::Type::IS_PACKET(),
|
||||
push @pq, APRSIS2::ISPacket->new({
|
||||
'type' => APRSIS2::ISPacket::Type::IS_PACKET(),
|
||||
'is_packet_data' => $p
|
||||
});
|
||||
}
|
||||
|
||||
my $im = IS2Message->new({
|
||||
'type' => IS2Message::Type::IS_PACKET(),
|
||||
my $im = APRSIS2::IS2Message->new({
|
||||
'type' => APRSIS2::IS2Message::Type::IS_PACKET(),
|
||||
'is_packet' => \@pq
|
||||
});
|
||||
|
||||
|
|
@ -274,9 +276,9 @@ sub wait_signature($)
|
|||
# wait for server signature
|
||||
my $t = time();
|
||||
while (my $l = $self->is2_frame_in()) {
|
||||
my $sig = $l->server_signature;
|
||||
my $sig = $l->get_server_signature();
|
||||
|
||||
if ($l->type == IS2Message::Type::SERVER_SIGNATURE()) {
|
||||
if ($l->get_type() == APRSIS2::IS2Message::Type::SERVER_SIGNATURE()) {
|
||||
if (!$sig) {
|
||||
$self->{'error'} = "SERVER_SIGNATURE type, but no server signature message";
|
||||
return 0;
|
||||
|
|
@ -285,7 +287,7 @@ sub wait_signature($)
|
|||
#warn sprintf("got server signature: serverid '%s' app '%s' version '%s'\n",
|
||||
# $sig->username, $sig->app_name, $sig->app_version);
|
||||
} else {
|
||||
$self->{'error'} = "Wrong type of message received instead of SERVER_SIGNATURE: " . $l->type;
|
||||
$self->{'error'} = "Wrong type of message received instead of SERVER_SIGNATURE: " . $l->get_type();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -306,10 +308,10 @@ sub ping($)
|
|||
my $timeout = 2;
|
||||
my $reqid = int(rand(2**30));
|
||||
|
||||
my $im = IS2Message->new({
|
||||
'type' => IS2Message::Type::KEEPALIVE_PING(),
|
||||
'keepalive_ping' => IS2KeepalivePing->new({
|
||||
'ping_type' => IS2KeepalivePing::PingType::REQUEST(),
|
||||
my $im = APRSIS2::IS2Message->new({
|
||||
'type' => APRSIS2::IS2Message::Type::KEEPALIVE_PING(),
|
||||
'keepalive_ping' => APRSIS2::IS2KeepalivePing->new({
|
||||
'ping_type' => APRSIS2::IS2KeepalivePing::PingType::REQUEST(),
|
||||
'request_id' => $reqid,
|
||||
})
|
||||
});
|
||||
|
|
@ -319,23 +321,24 @@ sub ping($)
|
|||
my $t = time();
|
||||
|
||||
while (my $l = $self->is2_frame_in($timeout)) {
|
||||
if ($l->type != IS2Message::Type::KEEPALIVE_PING()) {
|
||||
warn "IS2 ping: Unexpected type of frame received: " . $l->type . "\n";
|
||||
if ($l->get_type() != APRSIS2::IS2Message::Type::KEEPALIVE_PING()) {
|
||||
warn "IS2 ping: Unexpected type of frame received: " . $l->get_type() . "\n";
|
||||
next;
|
||||
}
|
||||
|
||||
if (!defined $l->keepalive_ping) {
|
||||
my $ping = $l->get_keepalive_ping();
|
||||
if (!defined $ping) {
|
||||
$self->{'error'} = "IS2 ping reply does not have keepalive_ping payload";
|
||||
return undef;
|
||||
}
|
||||
|
||||
if ($l->keepalive_ping->ping_type != IS2KeepalivePing::PingType::REPLY()) {
|
||||
$self->{'error'} = "IS2 ping: Wrong type of frame received: " . $l->type;
|
||||
if ($ping->get_ping_type() != APRSIS2::IS2KeepalivePing::PingType::REPLY()) {
|
||||
$self->{'error'} = "IS2 ping: Wrong type of ping frame received: " . $ping->get_ping_time();
|
||||
return undef;
|
||||
}
|
||||
|
||||
if ($l->keepalive_ping->request_id != $reqid) {
|
||||
$self->{'error'} = "IS2 ping: Request id mismatch, sent $reqid, got " . $l->keepalive_ping->request_id;
|
||||
if ($ping->get_request_id() != $reqid) {
|
||||
$self->{'error'} = "IS2 ping: Request id mismatch, sent $reqid, got " . $ping->get_request_id();
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
|
@ -359,8 +362,8 @@ sub get_packets($;$)
|
|||
my $t = time();
|
||||
|
||||
while (my $l = $self->is2_frame_in($timeout)) {
|
||||
my $ips = $l->is_packet;
|
||||
if ($l->type == IS2Message::Type::IS_PACKET()) {
|
||||
if ($l->get_type() == APRSIS2::IS2Message::Type::IS_PACKET()) {
|
||||
my $ips = $l->get_is_packet_list();
|
||||
if (!$ips) {
|
||||
$self->{'error'} = "IS_PACKET type, but no packets";
|
||||
return undef;
|
||||
|
|
@ -369,17 +372,17 @@ sub get_packets($;$)
|
|||
my @pa;
|
||||
|
||||
foreach my $ip (@{ $ips }) {
|
||||
if ($ip->type != ISPacket::Type::IS_PACKET()) {
|
||||
$self->{'error'} = sprintf("ISPacket type %d unsupported", $ip->type);
|
||||
if ($ip->get_type() != APRSIS2::ISPacket::Type::IS_PACKET()) {
|
||||
$self->{'error'} = sprintf("ISPacket type %d unsupported", $ip->get_type());
|
||||
return undef;
|
||||
}
|
||||
|
||||
push @pa, $ip->is_packet_data;
|
||||
push @pa, $ip->get_is_packet_data();
|
||||
}
|
||||
|
||||
return @pa;
|
||||
} else {
|
||||
$self->{'error'} = "Wrong type of frame received: " . $l->type;
|
||||
$self->{'error'} = "Wrong type of frame received: " . $l->get_type();
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
|
@ -415,10 +418,10 @@ sub set_filter($$)
|
|||
|
||||
my $reqid = int(rand(2**30));
|
||||
|
||||
my $im = IS2Message->new({
|
||||
'type' => IS2Message::Type::PARAMETER(),
|
||||
'parameter' => IS2Parameter->new({
|
||||
'type' => IS2Parameter::Type::PARAMETER_SET(),
|
||||
my $im = APRSIS2::IS2Message->new({
|
||||
'type' => APRSIS2::IS2Message::Type::PARAMETER(),
|
||||
'parameter' => APRSIS2::IS2Parameter->new({
|
||||
'type' => APRSIS2::IS2Parameter::Type::PARAMETER_SET(),
|
||||
'request_id' => $reqid, # todo: sequential
|
||||
'filter_string' => $filter
|
||||
})
|
||||
|
|
@ -428,19 +431,19 @@ sub set_filter($$)
|
|||
|
||||
my $t = time();
|
||||
while (my $l = $self->is2_frame_in()) {
|
||||
my $rep = $l->parameter;
|
||||
if ($l->type == IS2Message::Type::PARAMETER()) {
|
||||
if ($l->get_type() == APRSIS2::IS2Message::Type::PARAMETER()) {
|
||||
my $rep = $l->get_parameter();
|
||||
if (!$rep) {
|
||||
$self->{'error'} = "PARAMETER type, but no parameter message";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($rep->request_id != $reqid) {
|
||||
$self->{'error'} = "PARAMETER reply, wrong request id " . $rep->request_id . ", expected $reqid";
|
||||
if ($rep->get_request_id() != $reqid) {
|
||||
$self->{'error'} = "PARAMETER reply, wrong request id " . $rep->get_request_id() . ", expected $reqid";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ($rep->type != IS2Parameter::Type::PARAMETER_APPLIED()) {
|
||||
if ($rep->get_type() != APRSIS2::IS2Parameter::Type::PARAMETER_APPLIED()) {
|
||||
$self->{'error'} = sprintf("filter set reply: not applied");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -448,7 +451,7 @@ sub set_filter($$)
|
|||
# todo: check sequence
|
||||
return 1;
|
||||
} else {
|
||||
$self->{'error'} = "Wrong type of response received for PARAMETER_SET: " . $l->type;
|
||||
$self->{'error'} = "Wrong type of response received for PARAMETER_SET: " . $l->get_type();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -528,8 +531,8 @@ sub is2_frame_in($;$)
|
|||
my $frame = substr($self->{'ibuf'}, 4, $frame_len);
|
||||
$self->{'ibuf'} = substr($self->{'ibuf'}, $need_bytes);
|
||||
|
||||
my $is2_msg = IS2Message->decode($frame);
|
||||
|
||||
my $is2_msg = APRSIS2::IS2Message->decode($frame);
|
||||
#warn "decoded: " . Dumper($is2_msg) . "\n";
|
||||
#warn "left in ibuf: " . length($self->{'ibuf'}) . "\n";
|
||||
return $is2_msg;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue