示例#1
0
文件: msi.c 项目: GrayHatter/toxcore
void handle_push(MSICall *call, const MSIMessage *msg)
{
    assert(call);

    LOGGER_DEBUG(call->session->messenger->log, "Session: %p Handling 'push' friend: %d", call->session,
                 call->friend_number);

    if (!msg->capabilities.exists) {
        LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid capabilities on 'push'");
        call->error = msi_EInvalidMessage;
        goto FAILURE;
    }

    switch (call->state) {
        case msi_CallActive: {
            /* Only act if capabilities changed */
            if (call->peer_capabilities != msg->capabilities.value) {
                LOGGER_INFO(call->session->messenger->log, "Friend is changing capabilities to: %u", msg->capabilities.value);

                call->peer_capabilities = msg->capabilities.value;

                if (invoke_callback(call, msi_OnCapabilities) == -1) {
                    goto FAILURE;
                }
            }
        }
        break;

        case msi_CallRequesting: {
            LOGGER_INFO(call->session->messenger->log, "Friend answered our call");

            /* Call started */
            call->peer_capabilities = msg->capabilities.value;
            call->state = msi_CallActive;

            if (invoke_callback(call, msi_OnStart) == -1) {
                goto FAILURE;
            }
        }
        break;

        /* Pushes during initialization state are ignored */
        case msi_CallInactive: // fall-through
        case msi_CallRequested: {
            LOGGER_WARNING(call->session->messenger->log, "Ignoring invalid push");
        }
        break;
    }

    return;

FAILURE:
    send_error(call->session->messenger, call->friend_number, call->error);
    kill_call(call);
}
示例#2
0
文件: msi.c 项目: GrayHatter/toxcore
void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data)
{
    (void)m;
    MSISession *session = (MSISession *)data;

    switch (status) {
        case 0: { /* Friend is now offline */
            LOGGER_DEBUG(m->log, "Friend %d is now offline", friend_number);

            pthread_mutex_lock(session->mutex);
            MSICall *call = get_call(session, friend_number);

            if (call == NULL) {
                pthread_mutex_unlock(session->mutex);
                return;
            }

            invoke_callback(call, msi_OnPeerTimeout); /* Failure is ignored */
            kill_call(call);
            pthread_mutex_unlock(session->mutex);
        }
        break;

        default:
            break;
    }
}
示例#3
0
文件: msi.c 项目: GrayHatter/toxcore
void handle_pop(MSICall *call, const MSIMessage *msg)
{
    assert(call);

    LOGGER_DEBUG(call->session->messenger->log, "Session: %p Handling 'pop', friend id: %d", call->session,
                 call->friend_number);

    /* callback errors are ignored */

    if (msg->error.exists) {
        LOGGER_WARNING(call->session->messenger->log, "Friend detected an error: %d", msg->error.value);
        call->error = msg->error.value;
        invoke_callback(call, msi_OnError);
    } else {
        switch (call->state) {
            case msi_CallInactive: {
                LOGGER_ERROR(call->session->messenger->log, "Handling what should be impossible case");
                abort();
            }

            case msi_CallActive: {
                /* Hangup */
                LOGGER_INFO(call->session->messenger->log, "Friend hung up on us");
                invoke_callback(call, msi_OnEnd);
            }
            break;

            case msi_CallRequesting: {
                /* Reject */
                LOGGER_INFO(call->session->messenger->log, "Friend rejected our call");
                invoke_callback(call, msi_OnEnd);
            }
            break;

            case msi_CallRequested: {
                /* Cancel */
                LOGGER_INFO(call->session->messenger->log, "Friend canceled call invite");
                invoke_callback(call, msi_OnEnd);
            }
            break;
        }
    }

    kill_call(call);
}
示例#4
0
static void callback_uiComboboxOnSelected( uiCombobox* c, void* d )
{
	lua_State* L = (lua_State*) d;
	if( L )
	{
		lua_pushinteger( L, uiComboboxSelected( c ) );
		invoke_callback( L, c, callback_OnSelected, 1 );
	}
}
示例#5
0
static void callback_uiSliderOnChanged( uiSlider* c, void* d )
{
	lua_State* L = (lua_State*) d;
	if( L )
	{
		lua_pushinteger( L, uiSliderValue( c ) );
		invoke_callback( L, c, callback_OnChanged, 1 );
	}
}
示例#6
0
static void callback_uiCheckboxOnToggled( uiCheckbox* c, void* d )
{
	lua_State* L = (lua_State*) d;
	if( L )
	{
		lua_pushboolean( L, uiCheckboxChecked( c ) );
		invoke_callback( L, c, callback_OnToggled, 1 );
	}
}
示例#7
0
static void callback_uiMenuItemOnClicked( uiMenuItem* i, uiWindow* w, void* d )
{
	lua_State* L = (lua_State*) d;
	if( L )
	{
		object_copy( L, w );
		invoke_callback( (lua_State*) d, i, callback_OnClicked, 1 );
	}
}
示例#8
0
static void callback_uiMultilineEntryOnChanged( uiMultilineEntry* c, void* d )
{
	lua_State* L = (lua_State*) d;
	if( L )
	{
		char* str = uiMultilineEntryText( c );
		lua_pushstring( L, str );
		uiFreeText( str );
		invoke_callback( L, c, callback_OnChanged, 1 );
	}
}
示例#9
0
static void callback_uiEditableComboboxOnChanged( uiEditableCombobox* c, void* d )
{
	lua_State* L = (lua_State*) d;
	if( L )
	{
		object_create( L, uiNewCombobox(), uiComboboxSignature, control_common, combobox_functions, 0 );
		char* text = uiEditableComboboxText( c );
		lua_pushstring( L, text );
		invoke_callback( L, c, callback_OnChanged, 1 );
		uiFreeText( text );
	}
}
示例#10
0
static void callback_uiColorButtonOnChanged( uiColorButton* c, void* d )
{
	lua_State* L = (lua_State*) d;
	if( L )
	{
		double r,g,b,a;
		uiColorButtonColor( c, &r, &g, &b, &a );
		lua_pushnumber( L, r );
		lua_pushnumber( L, g );
		lua_pushnumber( L, b );
		lua_pushnumber( L, a );
		invoke_callback( L, c, callback_OnChanged, 4 );
	}
}
示例#11
0
/**@brief Timeout handler for the advertisement slot timer. */
static void adv_slot_timeout(void * p_context)
{

    ret_code_t err_code;
    uint32_t active_slot_index = (uint32_t)p_context;

    es_adv_timing_evt_t evt;

    evt.slot_no = m_adv_timing_result.timing_results[active_slot_index].slot_no;

    evt.evt_id = m_adv_timing_result.timing_results[active_slot_index].is_etlm
                     ? ES_ADV_TIMING_EVT_ADV_ETLM
                     : ES_ADV_TIMING_EVT_ADV_SLOT;

    // Trigger an event for the next slot if this slot is not the last to be advertised in this event.
    // Note: since we check 'm_adv_timing_result.len_timing_results > 1' we can safely cast the result of
    //       the subtraction to a uint32.
    if (m_non_conn_adv_active && \
        m_adv_timing_result.len_timing_results > 1 && \
        active_slot_index < (uint32_t)(m_adv_timing_result.len_timing_results - 1))
    {
        err_code = app_timer_start( m_es_slot_timer,
                                    APP_TIMER_TICKS(m_adv_timing_result.timing_results[active_slot_index].delay_ms,
                                                    APP_TIMER_PRESCALER),
                                    (void*)(active_slot_index + 1));
        APP_ERROR_CHECK(err_code);
    }

#if APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1
    static uint32_t adv_event_cnt = 0;

    if (active_slot_index == 0)
    {
        adv_event_cnt++;
    }

    if (frame_to_adv_is_tlm(&evt) && !tlm_should_be_advertised(adv_event_cnt))
    {
        return;
    }
#endif // APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1

    invoke_callback(&evt);
}
示例#12
0
/**@brief  Update advertisement data and start connectable advertisements. */
static void connectable_adv_start(void)
{
    ble_gap_adv_params_t connectable_adv_params;
    ble_advdata_t        scrsp_data;
    ble_uuid_t           scrp_uuids[] = {{BLE_UUID_ESCS_SERVICE, m_ecs_uuid_type}};

    memset(&scrsp_data, 0, sizeof(scrsp_data));
    scrsp_data.name_type               = BLE_ADVDATA_FULL_NAME;
    scrsp_data.include_appearance      = false;
    scrsp_data.uuids_complete.uuid_cnt = sizeof(scrp_uuids) / sizeof(scrp_uuids[0]);
    scrsp_data.uuids_complete.p_uuids  = scrp_uuids;

    // As the data to be written does not depend on the slot_no, we can safely send
    es_adv_frame_fill_connectable_adv_data(&scrsp_data);

    get_adv_params(&connectable_adv_params, false, m_remain_connectable);
    adv_start(&connectable_adv_params);

    invoke_callback(ES_ADV_EVT_CONNECTABLE_ADV_STARTED);
}
示例#13
0
/**@brief Function handling events from @ref es_adv_timing.c.
 *
 * @param[in] p_evt Advertisement timing event.
 */
static void adv_timing_callback(const es_adv_timing_evt_t * p_evt)
{
    ret_code_t            err_code;
    ble_gap_adv_params_t  non_connectable_adv_params;
    const es_slot_reg_t * p_reg = es_slot_get_registry();

    // As new advertisement data will be loaded, stop advertising.
    err_code = sd_ble_gap_adv_stop();
    if (err_code != NRF_ERROR_INVALID_STATE)
    {
        APP_ERROR_CHECK(err_code);
    }

    // If a non-eTLM frame is to be advertised.
    if (p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_SLOT)
    {
        err_code = sd_ble_gap_tx_power_set(p_reg->slots[p_evt->slot_no].radio_tx_pwr);
        APP_ERROR_CHECK(err_code);

        es_adv_frame_fill_non_connectable_adv_data(p_evt->slot_no, false);
    }

    // If an eTLM frame is to be advertised
    else if (p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_ETLM)
    {
        err_code = sd_ble_gap_tx_power_set(p_reg->slots[p_reg->tlm_slot].radio_tx_pwr);
        APP_ERROR_CHECK(err_code);

        es_adv_frame_fill_non_connectable_adv_data(p_evt->slot_no, true);
    }

    invoke_callback(ES_ADV_EVT_NON_CONN_ADV);

    get_adv_params(&non_connectable_adv_params, true, m_remain_connectable);
    adv_start(&non_connectable_adv_params);
}
示例#14
0
static int callback_uiWindowOnClosing( uiWindow* w, void* d )
{
    invoke_callback( (lua_State*) d, w, callback_OnClosing, 0 );
    return 0;
}
示例#15
0
文件: msi.c 项目: GrayHatter/toxcore
void handle_init(MSICall *call, const MSIMessage *msg)
{
    assert(call);
    LOGGER_DEBUG(call->session->messenger->log,
                 "Session: %p Handling 'init' friend: %d", call->session, call->friend_number);

    if (!msg->capabilities.exists) {
        LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid capabilities on 'init'");
        call->error = msi_EInvalidMessage;
        goto FAILURE;
    }

    switch (call->state) {
        case msi_CallInactive: {
            /* Call requested */
            call->peer_capabilities = msg->capabilities.value;
            call->state = msi_CallRequested;

            if (invoke_callback(call, msi_OnInvite) == -1) {
                goto FAILURE;
            }
        }
        break;

        case msi_CallActive: {
            /* If peer sent init while the call is already
             * active it's probable that he is trying to
             * re-call us while the call is not terminated
             * on our side. We can assume that in this case
             * we can automatically answer the re-call.
             */

            LOGGER_INFO(call->session->messenger->log, "Friend is recalling us");

            MSIMessage out_msg;
            msg_init(&out_msg, requ_push);

            out_msg.capabilities.exists = true;
            out_msg.capabilities.value = call->self_capabilities;

            send_message(call->session->messenger, call->friend_number, &out_msg);

            /* If peer changed capabilities during re-call they will
             * be handled accordingly during the next step
             */
        }
        break;

        case msi_CallRequested: // fall-through
        case msi_CallRequesting: {
            LOGGER_WARNING(call->session->messenger->log, "Session: %p Invalid state on 'init'");
            call->error = msi_EInvalidState;
            goto FAILURE;
        }
    }

    return;
FAILURE:
    send_error(call->session->messenger, call->friend_number, call->error);
    kill_call(call);
}
示例#16
0
static void
dispatch_callback(ffi_cif* cif, void* resp, void** cbargs, void* user_data) {
  callback* cb = ((callback *)user_data); 
  JavaVM* jvm = cb->vm;
  JNIEnv* env = NULL;
  int was_attached = (*jvm)->GetEnv(jvm, (void *)&env, JNI_VERSION_1_4) == JNI_OK;
  jboolean needs_detach = was_attached ? JNI_FALSE : JNI_TRUE;
  thread_storage* tls = was_attached ? get_thread_storage(env) : NULL;

  if (!was_attached) {
    int attach_status = 0;
    JavaVMAttachArgs args;
    int daemon = JNI_FALSE;

    args.version = JNI_VERSION_1_2;
    args.name = NULL;
    args.group = NULL;
    if (cb->behavior_flags & CB_HAS_INITIALIZER) {
      AttachOptions options;
      options.daemon = JNI_FALSE; // default non-daemon
      options.detach = JNI_TRUE; // default detach behavior
      options.name = NULL;
      args.group = initializeThread(cb, &options);
      daemon = options.daemon ? JNI_TRUE : JNI_FALSE;
      needs_detach = options.detach ? JNI_TRUE : JNI_FALSE;
      args.name = options.name;
    }
    if (daemon) {
      attach_status = (*jvm)->AttachCurrentThreadAsDaemon(jvm, (void*)&env, &args);
    }
    else {
      attach_status = (*jvm)->AttachCurrentThread(jvm, (void *)&env, &args);
    }
    tls = get_thread_storage(env);
    if (tls) {
      snprintf(tls->name, sizeof(tls->name), "%s", args.name ? args.name : "<unconfigured native thread>");
      tls->needs_detach = needs_detach;
      tls->jvm_thread = JNI_FALSE;
    }
    // Dispose of allocated memory
    free(args.name);
    if (attach_status != JNI_OK) {
      fprintf(stderr, "JNA: Can't attach native thread to VM for callback: %d\n", attach_status);
      return;
    }
    if (args.group) {
      (*env)->DeleteWeakGlobalRef(env, args.group);
    }
  }
						
  if (!tls) {
    fprintf(stderr, "JNA: couldn't obtain thread-local storage\n");
    return;
  }

  // Give the callback glue its own local frame to ensure all local references
  // are properly disposed
  if ((*env)->PushLocalFrame(env, 16) < 0) {
    fprintf(stderr, "JNA: Out of memory: Can't allocate local frame\n");
  }
  else {
    invoke_callback(env, cb, cif, resp, cbargs);
    // Make note of whether the callback wants to avoid detach
    needs_detach = tls->needs_detach && !tls->jvm_thread;
    (*env)->PopLocalFrame(env, NULL);
  }
  
  if (needs_detach) {
    if ((*jvm)->DetachCurrentThread(jvm) != 0) {
      fprintf(stderr, "JNA: could not detach thread\n");
    }
  }
}
示例#17
0
        // 压入待解析数据
        void parse(char const* data, std::size_t size)
        {
            char const* buf = data;
            std::size_t len = size;

            while (len)
            {
                if (0 == pos_)
                {
                    // 缓冲区中无数据, 直接在上层缓冲区中尝试组包.
                    if (len < head_size)
                    {
                        // 不足一个封包头, 写入缓冲区即可
                        write_buffer(buf, len);
                        return ;
                    }
                    else
                    {
                        // 有完整的封包头, 进一步检测是否有完整的封包.
                        std::size_t packet_len = Sizer()(packethead(buf)) + head_size;
                        if (packet_len > size_)
                        {
                            // 封包长错误
                            invoke_callback(generate_error(bee::parse_error), 0, 0, 0);
                            return ;
                        }

                        if (len < packet_len)
                        {
                            // 不足一个封包, 放入缓冲区中, 等待后续数据.
                            write_buffer(buf, len);
                            return ;
                        }
                        else
                        {
                            // 有完整的封包, 直接处理.
                            invoke_callback(error_code(), &packethead(buf), buf + head_size, packet_len - head_size);
                            buf += packet_len;
                            len -= packet_len;
                            continue;
                        }
                    }
                }
                else if (pos_ < head_size)
                {
                    // 缓冲区中有数据, 但不足一个封包头, 尝试拼足一个封包头
                    std::size_t delta = head_size - pos_;
                    std::size_t cpy_size = (std::min)(delta, len);
                    write_buffer(buf, cpy_size);
                    buf += cpy_size;
                    len -= cpy_size;
                    continue;
                }
                else
                {
                    // 缓冲区中有完整的封包头
                    std::size_t packet_len = Sizer()(packethead(buf_)) + head_size;
                    if (packet_len > size_)
                    {
                        // 封包长错误
                        invoke_callback(generate_error(bee::parse_error), 0, 0, 0);
                        return ;
                    }

                    std::size_t delta = packet_len - pos_;
                    if (delta > len)
                    {
                        // 无法拼出一个完整的封包
                        write_buffer(buf, len);
                        return ;
                    }
                    else
                    {
                        // 可以拼出一个完整的封包
                        write_buffer(buf, delta);
                        invoke_callback(error_code(), &packethead(buf_), buf_ + head_size, pos_ - head_size);
                        pos_ = 0;
                        buf += delta;
                        len -= delta;
                        continue;
                    }
                }
            }
        }